不同形式的WCF服务契约接口
本文关键字:服务 契约 接口 WCF | 更新日期: 2023-09-27 17:53:22
看来我可以在以下三个不同版本的相同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
风格的方法转换成TAP的SomeMethodAsync
风格的方法,在它们的实现中使用async/await
,从而提高WCF服务的可伸缩性,而不会破坏现有的客户端。
此外,在。net 3.5和。net 4.0下,WCF服务的扩展也存在一些问题。它们在MSKB文章"WCF服务可能在负载下缓慢扩展"和CodeProject文章"调整WCF以构建高度可扩展的异步REST API"中都有记录。基本上,将服务契约api实现为自然异步是不够的,WCF运行时仍然阻塞请求线程。
- 有人知道这个问题是否已经在。net 4.5中修复了吗?x ,开箱即用的?或者仍然需要额外的调整?
WCF操作可以使用同步、EAP或(从。net 4.5开始)TAP来定义。从MSDN:
客户端可以向开发人员提供他们选择的任何编程模型,只要观察到底层的消息交换模式。因此,只要遵守指定的消息模式,服务也可以以任何方式实现操作。
你实际上可以在一个单一的契约接口中拥有所有三种模式,并且它们都与同一消息相关。
在网络上,如何执行操作是没有区别的。 WSDL (WCF从每个端点的ABC地址、绑定和契约构建的WSDL)不包含此信息。它由操作描述生成。
如果您查看ContractDescription
中使用的OperationDescription
类,您将看到每个操作都有这些属性:SyncMethod
, BeginMethod
, EndMethod
和TaskMethod
。在创建描述时,WCF将根据操作名称将所有方法组合为单个操作。如果在不同模式下具有相同名称的操作(例如不同的参数)之间存在一些不匹配,WCF将抛出一个异常,详细说明错误所在。WCF自动假定(可选)"Async"后缀用于基于任务的方法,"Begin/End"前缀用于APM。
svcutil
)生成代理类的实用程序可以为任何执行模式构建代理。它甚至不必是WCF服务。
在服务器端,如果实现了多个模式,WCF将按照以下优先顺序只使用一个: Task、Sync和APM。这是记录在MSDN的某个地方,我只是现在找不到它。但是你可以在这里查看参考源代码。
总之,只要不修改操作所代表的消息,就可以安全地更改服务器实现。
关于缩放(在我看来应该是另一个问题)
- WCF的节流默认值在。net 4.5中更新为更合理的值,并且现在依赖于处理器(见这里)。关于线程池的问题没有变化。问题源于完成端口线程池的初始大小,它最初设置为逻辑处理器数量的4倍。你可以使用
ThreadPool.SetMinThreads
来增加一些因子的数量(参见这篇文章)。此设置在客户端也可能是有益的。如果你在服务器端使用async(当调用其他服务,数据库等时),线程情况可能会显著改善,因为你不会浪费线程池中等待IO完成的线程。
在这种情况下,最好的办法是做大量的基准测试。