WCF中的AsyncPattern

 

(系列博文源自 http://pfelix.wordpress.com/,由笔者翻译并整理,转载请注明)

在wcf 的 service contract中, 服务接口方法定义都要求有 operation context这个标签。 在这个标签里有一个 AsyncPattern的属性用以定制 service的异步模型。

考虑如下接口定义:

1: [ServiceContract]
2: interface IService {
3: [OperationContract]
4: ReplyData Operation1(RequestData rd);
5:
6: [OperationContract(AsyncPattern = true)]
7: IAsyncResult BeginOperation2(RequestData rd, AsyncCallback ac, object obj);
8: ReplyData EndOperation2(IAsyncResult ar);
9: }

service interface

  • 第一个服务方法定义中, AsyncPattern默认为false。 这是一个简单的 request-response方法 'Operation1'. 在默认设置下,这个方法由server端同步实现。 具体过程是由 WCF Dispatcher调用这个方法,生成传入参数,在这个方法执行过程中会占用这个service线程,最终返回reply,并由wcf生成返回消息传回客户端。
  • 第二个服务方法定义中, AsyncPattern设成true,同样定义了一个request-response方法 'Operation2'。然而, 这个方法实现要求是一个包含两个方法:BeginOperation2, EndOperation2的异步实现。在这里的‘异步’ 意味着
    • WCF dispatcher 调用 BeginOperation2 , 生成传入参数和一个异步回调, 还有一些状态信息。
    • 这个方法开始执行并最终返回一个IAsyncResult
    • 当这个方法执行结束时会调用AsyncCallback 。
    • 这个AsyncCallback 是由wcf实现 会接下来调用 EndOperation2 收集返回值并把消息传回给客户端。     

需要注意的是,即使设置了AsyncPattern, 在通信层面而言这个service依然是一个 request-response 模型。 这个异步只是service 的实现细节。 参考生成的wsdl定义:  

1: <wsdl:portType name="IService">
2:
3: <wsdl:operation name="Operation1">
4: <wsdl:input wsaw:Action="..." message="..." />
5: <wsdl:output wsaw:Action="..." message="..." />
6: </wsdl:operation>
7:
8: <wsdl:operation name="Operation2">
9: <wsdl:input wsaw:Action="..." message="..." />
10: <wsdl:output wsaw:Action="..." message="..." />
11: </wsdl:operation>
12:
13: </wsdl:portType>

这并不会改变service的通信模型,有别于普遍意义上的 “异步服务”。

那么,这种实现方式有什么意义? 或者说在何种场景下应该使用这种实现方式?

砖家说,当服务实现中会长时间block住当前服务线程时就应该考虑这种实现方式。

结合上图应该能比较容易理解这种方式带来的优势, 在上图的例子中这种实现方式能在开始 io前释放服务线程, 并在 io结束后重新获得一个线程做后续操作。

理论上来说这种方式就不会存在一个‘被阻塞’的线程,以节约线程资源来提升service并发。

最后提一下在client端这个属性的作用。

当使用 svcutil.exe时加上 /async 会生成以下服务器代理接口定义:

1: public interface IService {
2:
3: // Operation 1 synchronous method
4: [System.ServiceModel.OperationContractAttribute(Action=".../Operation1", ReplyAction=".../Operation1Response")]
5: ReplyData Operation1(RequestData rd);
6:
7: // Operation 1 asynchronous method pair
8: [System.ServiceModel.OperationContractAttribute(AsyncPattern=true, Action=".../Operation1", ReplyAction=".../Operation1Response")]
9: System.IAsyncResult BeginOperation1(RequestData rd, System.AsyncCallback callback, object asyncState);
10: ReplyData EndOperation1(System.IAsyncResult result); 11:
12: // Operation 2 synchronous method
13: [System.ServiceModel.OperationContractAttribute(Action=".../Operation2", ReplyAction=".../Operation2Response")]
14: ReplyData Operation2(AsyncPattern.Client.AsyncClient.RequestData rd);
15:
16: // Operation 2 asynchronous method pair
17: [System.ServiceModel.OperationContractAttribute(AsyncPattern=true, Action=".../Operation2", ReplyAction=".../Operation2Response")]
18: System.IAsyncResult BeginOperation2(RequestData rd, System.AsyncCallback callback, object asyncState);
19: ReplyData EndOperation2(System.IAsyncResult result); 20:
21: }

如果理解了一开始的部分,很容易想到这根服务器端的实现方式无关。 这只是客户端的一种内部实现方式。

其效果就是调用服务器时会立刻返回(而不阻塞),再由调用EndOperation的形式得到执行结果。

值得一提的是类似的效果虽然可以通过多线程来实现。 但依然不会有wcf Async机制高效, 因为wcf 的异步模型是基于通信层支持, 并不会阻塞任何一个线程。而多线程实现依然会阻塞线程池中的异步线程。

(译者:多数情况而言在客户端这点优势倒没啥意义。。。。)

WCF中的AsyncPattern的更多相关文章

  1. WCF技术剖析之十一:异步操作在WCF中的应用(下篇)

    原文:WCF技术剖析之十一:异步操作在WCF中的应用(下篇) 说完了客户端的异步服务调用(参阅WCF技术剖析之十一:异步操作在WCF中的应用(上篇)),我们在来谈谈服务端如何通过异步的方式为服务提供实 ...

  2. WCF中的异步实现

    对于WCF中通讯的双方来说,客户端可以异步的调用服务:服务端对服务也能以异步的方式实现. 目录: 1.WCF客户端异步调用服务 2.服务端的异步实现 WCF客户端异步调用服务主要通过生成异步的代理类, ...

  3. WCF中,通过C#代码或App.config配置文件创建ServiceHost类

    C# static void Main(string[] args) { //创建宿主的基地址 Uri baseAddress = new Uri("http://localhost:808 ...

  4. WCF学习之旅—WCF中传统的异常处理(十六)

    WCF中的异常处理 在软件开发过程中,不可能没有异常的出现,所以在开发过程中,对不可预知的异常进行解决时,异常处理显得尤为重要.对于一般的.NET系统来说,我们简单地借助try/catch可以很容易地 ...

  5. 在Wcf中应用ProtoBuf替代默认的序列化器

    Google的ProtoBuf序列化器性能的牛逼已经有目共睹了,可以把它应用到Socket通讯,队列,Wcf中,身为dotnet程序员一边期待着不久后Grpc对dotnet core的支持更期待着Wc ...

  6. ajax调用本地wcf中的post和get

    我们可以通过jQuery调用本地或者远程的wcf服务,本文讲解的是对本地wcf服务的post和get调用方式. post和get到底有什么区别呢?此处不作详述. 但是,post对请求的数据格式更为严格 ...

  7. 在 WCF 中使用高效的 BinaryFormatter 序列化

    本文将定义一个 WCF 终结点行为扩展,以在 WCF 中使用更高效的 BinaryFormatter 进行二进制序列化,并实现对是否使用传统二进制序列化功能的可配置. 介绍 实现步骤 使用方法 效果 ...

  8. 【WCF】WCF中的InstanceContext与ConcurrencyMode【转】

    一.前言 最近忙于公司的在线升级项目,一个人要负责公司四大产品的在线升级,这四个产品是在Revit中以插件形式存在的,目前基于WCF来实现.等客户总量突破5万了,再重新用socket实现. 由于有服务 ...

  9. WCF初探-28:WCF中的并发

    理解WCF中的并发机制 在对WCF并发机制进行理解时,必须对WCF初探-27:WCF中的实例化进行理解,因为WCF中的并发特点是伴随着服务实例上下文实现的.WCF的实例上下文模型可以通过Instanc ...

随机推荐

  1. Linux中进程控制块PCB-------task_struct结构体结构

    Linux中task_struct用来控制管理进程,结构如下: struct task_struct { //说明了该进程是否可以执行,还是可中断等信息 volatile long state; // ...

  2. C# 获取QQ好友列表信息的实现

    分析部分 当我们访问QQ空间的时候,大家可以在右侧的发现一个这样的统计信息  当点击这个链接的时候,会跳转到  这样一个URL 这个URl可以管理好友,当然也就能读取到好友  上面我们是在浏览器中的操 ...

  3. 升级python之后yum不可用

    #修改yum文件 vi /usr/bin/yum 将文件头部的 #!/usr/bin/python 改为默认的python文件,例如 #!/usr/bin/python2.7.3 整个过程完成了. 同 ...

  4. 蓝桥杯 2014本科C++ B组 李白打酒 三种实现方法 枚举/递归

    标题:李白打酒 话说大诗人李白,一生好饮.幸好他从不开车. 一天,他提着酒壶,从家里出来,酒壶中有酒2斗.他边走边唱: 无事街上走,提壶去打酒. 逢店加一倍,遇花喝一斗. 这一路上,他一共遇到店5次, ...

  5. Android开发---开发文档翻译

    2014.11.24 1:ClipData类:用于表示剪切的数据,此剪切的数据可以是复杂类型,包括一个或多个条目实例 (1)基础知识 >公共类:public class >嵌套类:Clip ...

  6. 改变bootstrapSwitch按钮状态

    $('.switch-state').bootstrapSwitch('state',true);

  7. C和FORTRAN的快速傅里叶/余弦/正弦变换(Fast Fourier/Cosine/Sine Transform)开源库分享

    Takuya Ooura: General Purpose FFT Package, http://www.kurims.kyoto-u.ac.jp/~ooura/fft.html. Free C & ...

  8. .net 反射构造你自己的“匿名”对象

    由于近来项目的底层架构某些特殊需求及场景的需要要求动态build一个对象, 属性名称个类与类型都是外界动态传入的. 不多说废话,直接上我最原始的代码: public static Type GetMy ...

  9. 跟我学: 使用 fireasy 搭建 asp.net core 项目系列之三 —— 配置

    ==== 目录 ==== 跟我学: 使用 fireasy 搭建 asp.net core 项目系列之一 —— 开篇 跟我学: 使用 fireasy 搭建 asp.net core 项目系列之二 —— ...

  10. MVC 基本工具(Visual Studio 的单元测试、使用Moq)

    3.Visual Studio 的单元测试 有很多.NET单元测试包,其中很多是开源和免费的.本文打算使用 Visual Studio 附带的内建单元测试支持,但其他一些.NET单元测试包也是可用的. ...