WCF服务契约接口的不同forms

看来我可以在以下三个不同版本的同一个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); } 

现有的testing客户端应用程序保持工作,无需重新编译或触摸。 如果我重新编译服务并将其引用重新导入到客户端应用程序中,那么WSDL定义将保持不变 ,即1:1。

我的问题:

  • 这是我可以信赖的合法行为吗? 它logging在任何地方吗?

我们的想法是将一组同步SomeMethod风格的方法转换为TAP SomeMethodAsync风格的方法,在其实现中使用async/await ,从而提高WCF服务的可伸缩性,而不会破坏现有的客户端。

另外,在.NET 3.5和.NET 4.0下,WCF服务扩展方面已经出现了一些问题。 他们在MSKB文章“WCF服务可能在负载下缓慢扩展”以及CodeProject文章“调整WCF构build高度可扩展的asynchronousREST API”中有logging 。 基本上,将服务合约API实现为自然的asynchronous是不够的,WCF运行时仍然阻塞了请求线程。

  • 有谁知道如果这个问题已经修复了.NET 4.5.x ,开箱即用? 或者额外的调整仍然是必需的?

WCF操作可以使用同步,EAP或(从.NET 4.5起)TAP来定义。 来自MSDN :

只要观察到潜在的消息交换模式,客户可以向开发者提供他们select的任何编程模型。 所以服务也可以以任何方式实现操作,只要遵守规定的消息模式即可。

实际上,您可以在单个合同界面中拥有所有3种模式,并且它们都与相同的消息有关。

在电线上,执行操作没有任何区别。 WSDL(WCF从每个端点的ABC地址,绑定和合约构build)不包含这个信息。 它是从操作描述中生成的。

如果您查看ContractDescription使用的OperationDescription类,则会看到每个操作都具有以下属性: SyncMethodBeginMethodEndMethodTaskMethod 。 在创build描述时,WCF将根据操作名称将所有方法合并为一个操作。 如果在不同模式(例如,不同的参数)下具有相同名称的操作之间存在一些不匹配的情况,WCF会抛出一个exception,详细说明错误的具体情况。 WCF自动为基于任务的方法假设(可选)“asynchronous”后缀,以及APM的开始/结束前缀。

客户端和服务器端在这个意义上是完全不相关的。 从WSDL( svcutil )生成代理类的实用程序可以为任何执行模式构build代理。 它甚至不必是一个WCF服务。

在服务器端,如果实现了多个模式,WCF将按照以下优先顺序使用一个 :Task,Sync和APM。 这是logging在MSDN的某处,我现在找不到它。 但是你可以看看这里的参考资源。

总之,只要不修改操作代表的消息,就可以安全地更改服务器实现。

关于缩放(IMO应该是一个不同的问题)

  • WCF的限制默认值已在.NET 4.5中更新为更合理的值,现在依赖于处理器(请参阅此处 )。
  • 关于线程池问题没有任何改变。 问题源于完成端口线程池的初始大小,它最初设置为逻辑处理器数量的4倍。 你可以使用ThreadPool.SetMinThreads来增加一些因素的数量(见这篇文章 )。 这个设置对于客户端也是有益的。

如果在服务器端使用asynchronous(在调用其他服务,数据库等时),线程情况可能会显着改善,因为您不会浪费正在等待IO完成的线程池线程。

在这些情况下最好的做法是做很多基准。