WCF服务契约接口的不同形式 [英] Different forms of the WCF service contract interface

查看:30
本文介绍了WCF服务契约接口的不同形式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

看来我可以在相同 WCF 合约接口 API 的以下三个不同版本之间自由切换,而不会破坏客户端:

It appears I can freely switch between the following three different versions of the same WCF contract interface API, without breaking the clients:

[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.

The existing test client app keeps working without any recompiling or touching. If I do recompile the service and re-import its reference into the client app, the WSDL definition remains the same, 1:1.

我的问题:

  • 这是我可以信赖的合法行为吗?它是否在任何地方都有记录?
  • Is it a legit behavior I can rely on? Is it documented anywhere?

想法是将一组同步的SomeMethod风格的方法转换成TAPSomeMethodAsync风格的方法,在async/await中使用它们的实现,从而在不破坏现有客户端的情况下提高 WCF 服务的可伸缩性.

The idea is to convert a set of synchronous SomeMethod-style methods into TAP SomeMethodAsync-style methods, to use async/await in their implementation and thus improve the WCF service scalability, without breaking existing clients.

此外,在 .NET 3.5 和 .NET 4.0 下 WCF 服务扩展存在已知问题.MSKB 文章 WCF 服务可能会在负载下缓慢扩展" 和 CodeProject 文章 调整 WCF 以构建高度可扩展的异步 REST API".基本上,将服务契约 API 实现为自然异步是不够的,WCF 运行时仍然阻塞请求线程.

Also, there have been known woes with WCF service scaling under .NET 3.5 and .NET 4.0. They are documented in the MSKB article "WCF service may scale up slowly under load" and the CodeProject article "Tweaking WCF to build highly scalable async REST API". Basically, it wasn't enough to implement the service contract APIs as naturally asynchronous, the WCF runtime still was blocking the request thread.

  • 有谁知道此问题是否已针对 .NET 4.5.x 解决,开箱即用?或者仍然需要额外的调整?
  • Does anyone know if this problem has been fixed for .NET 4.5.x, out-of-the-box? Or the additional tweaks are still required?

推荐答案

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

WCF operations can be defined using either synchronous, EAP or (as of .NET 4.5) TAP. From MSDN:

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

Clients can offer the developer any programming model they choose, so long as the underlying message exchange pattern is observed. So, too, can services implement operations in any manner, so long as the specified message pattern is observed.

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

You can actually have all 3 patterns in a single contract interface, and they would all relate to the same message.

在线上,执行操作的方式没有区别. WSDL(WCF 根据每个端点的 ABC - 地址、绑定和合同构建)不包含此信息.它是从操作描述生成的.

On the wire, there's no difference how you execute the operations. WSDL (which WCF builds from each endpoint's ABC - address, binding and contract) doesn't contain this information. It is generated from operation descriptions.

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

If you look at the OperationDescription class, which is used in a ContractDescription, you'll see each operation has these properties: SyncMethod, BeginMethod, EndMethod and TaskMethod. When creating a description, WCF will combine all the methods according to the operation's name into a single operation. If there's some mismatch between operations with the same name in different patterns (e.g. different parameters) WCF would throw an exception detailing exactly what's wrong. WCF automatically assumes (optional) "Async" suffix for Task-based methods, and Begin/End prefix for APM.

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

The client and server side are completely unrelated in this sense. The utility that generates proxy classes from WSDL (svcutil), can build proxies for any execution pattern. It doesn't even have to be a WCF service.

在服务器端,如果实现了多个模式,WCF 将只使用一个,按以下优先顺序:任务、同步和 APM.这在 MSDN 的某处有记录,我现在找不到.但是您可以在此处查看参考源.

On the server side, if more than one pattern is implemented, WCF will use just one in the following order of precedence: Task, Sync and APM. This is documented somewhere in MSDN, I just can't find it right now. But you can look at the reference source here.

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

In conclusion, you can safely change your server implementation as long as you don't modify the message the operation represents.

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

Regarding the scaling (should be a different question IMO)

  • WCF 的限制默认值已在 .NET 4.5 中更新为更合理的值,并且现在依赖于处理器(请参阅 这里).
  • 线程池问题没有变化.问题源于完成端口线程池的初始大小,它最初设置为逻辑处理器数量的 4 倍.您可以使用 ThreadPool.SetMinThreads 将数量增加一些因素(参见 这篇文章).此设置也可能对客户端有益.
  • WCF's throttling default values have been updated in .NET 4.5 to much more reasonable values and are now processor-dependent (see here).
  • There's no change in regards to the thread-pool issue. The problem stems from the initial size of the completion port thread-pool, which is initially set to 4 times the amount of the logical processors. You can use ThreadPool.SetMinThreads to increase the amount by some factor (see this post). This setting could also be beneficial on the client side.

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

If you use async on the server side (when calling other services, database, etc.), the threading situation could improve dramatically because you won't be wasting thread-pool threads that are just waiting for IO to complete.

在这些情况下最好的做法是进行大量的基准测试.

The best thing in these situations is to do a LOT of benchmarking.

这篇关于WCF服务契约接口的不同形式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆