不同形式的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服务契约接口

WCF操作可以使用同步、EAP或(从。net 4.5开始)TAP来定义。从MSDN:

客户端可以向开发人员提供他们选择的任何编程模型,只要观察到底层的消息交换模式。因此,只要遵守指定的消息模式,服务也可以以任何方式实现操作。

你实际上可以在一个单一的契约接口中拥有所有三种模式,并且它们都与同一消息相关。

在网络上,如何执行操作是没有区别的。 WSDL (WCF从每个端点的ABC地址、绑定和契约构建的WSDL)不包含此信息。它由操作描述生成。

如果您查看ContractDescription中使用的OperationDescription类,您将看到每个操作都有这些属性:SyncMethod, BeginMethod, EndMethodTaskMethod。在创建描述时,WCF将根据操作名称将所有方法组合为单个操作。如果在不同模式下具有相同名称的操作(例如不同的参数)之间存在一些不匹配,WCF将抛出一个异常,详细说明错误所在。WCF自动假定(可选)"Async"后缀用于基于任务的方法,"Begin/End"前缀用于APM。

在这个意义上,客户端和服务器端是完全不相关的。从WSDL (svcutil)生成代理类的实用程序可以为任何执行模式构建代理。它甚至不必是WCF服务。 在服务器端,如果实现了多个模式,WCF将按照以下优先顺序只使用一个: Task、Sync和APM。这是记录在MSDN的某个地方,我只是现在找不到它。但是你可以在这里查看参考源代码。

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

关于缩放(在我看来应该是另一个问题)

    WCF的节流默认值在。net 4.5中更新为更合理的值,并且现在依赖于处理器(见这里)。关于线程池的问题没有变化。问题源于完成端口线程池的初始大小,它最初设置为逻辑处理器数量的4倍。你可以使用ThreadPool.SetMinThreads来增加一些因子的数量(参见这篇文章)。此设置在客户端也可能是有益的。

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

在这种情况下,最好的办法是做大量的基准测试。