似乎我可以在以下三个不同版本的同一个WCF合约接口API之间自由切换,而不会破坏客户端:
[ServiceContract]
interface IService
{
// Either synchronous
// [OperationContract]
// int SomeMethod(int arg);
// Or TAP
[OperationContract]
Task<int> SomeMethodAsync(int arg);
// Or APM
// [OperationContract(AsyncPattern = true)]
// IAsyncResult BeginSomeMethod(int arg, AsyncCallback callback, object state);
// int EndSomeMethod(IAsyncResult ar);
}
现有的测试客户端应用程序在没有任何重新编译或接触的情况下继续工作。如果我重新编译服务并将其引用重新导入到客户端应用程序中,WSDL定义仍然是相同的,即1:1。
我的问题:
其思想是将一组同步的SomeMethod
-style方法转换为TAP SomeMethodAsync
-style方法,以便在其实现中使用async/await
,从而在不破坏现有客户端的情况下提高WCF服务的可扩展性。
此外,在WCF3.5和.NET 4.0下,.NET服务伸缩也存在一些已知的问题。它们记录在MSKB文章"WCF service may scale up slowly under load"和CodeProject文章"Tweaking WCF to build highly scalable async REST API"中。基本上,仅将服务契约API实现为自然异步是不够的,WCF运行时仍然阻塞请求线程。
发布于 2014-04-08 16:27:04
WCF操作可以使用synchronous、EAP或(从.NET 4.5开始) TAP来定义。来自MSDN
只要遵循底层的消息交换模式,
客户端就可以为开发人员提供他们选择的任何编程模型。因此,只要遵循指定的消息模式,服务也可以以任何方式实现操作。
实际上,您可以在单个约定接口中包含所有3种模式,并且它们都与同一消息相关。
WSDL (从每个端点的ABC地址、绑定和协定构建而来)不包含这些信息。由操作描述生成。
如果查看ContractDescription
中使用的OperationDescription
类,就会发现每个操作都有以下属性:SyncMethod
、BeginMethod
、EndMethod
和TaskMethod
。在创建描述时,WCF会根据操作名称将所有方法组合到一个操作中。如果在不同模式(例如,不同参数)中具有相同名称的操作之间存在一些不匹配,WCF将抛出一个异常,详细说明错误所在。WCF自动假定(可选)基于任务的方法使用"Async“后缀,APM使用Begin/End前缀。
从这个意义上讲,客户端和服务器端是完全无关的。从WSDL (svcutil
)生成代理类的实用程序可以为任何执行模式构建代理。它甚至不需要是WCF服务。
在服务器端,如果实现了多个模式,WCF将按以下优先顺序只使用一个:任务、同步和APM。这是在MSDN的某个地方记录的,我只是现在找不到它。但您可以查看参考源here。
总之,只要不修改操作表示的消息,就可以安全地更改服务器实现。
关于缩放(应该是一个不同的问题)
在.NET 4.5中,
ThreadPool.SetMinThreads
将金额增加某个因子(请参阅this post)。此设置对客户端也有好处。如果您在服务器端使用异步(当调用其他服务、数据库等时),线程情况可能会显著改善,因为您不会浪费正在等待IO完成的线程池线程。
在这些情况下,最好的做法是进行大量的基准测试。
https://stackoverflow.com/questions/22623922
复制相似问题