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的更多相关文章
- WCF技术剖析之十一:异步操作在WCF中的应用(下篇)
原文:WCF技术剖析之十一:异步操作在WCF中的应用(下篇) 说完了客户端的异步服务调用(参阅WCF技术剖析之十一:异步操作在WCF中的应用(上篇)),我们在来谈谈服务端如何通过异步的方式为服务提供实 ...
- WCF中的异步实现
对于WCF中通讯的双方来说,客户端可以异步的调用服务:服务端对服务也能以异步的方式实现. 目录: 1.WCF客户端异步调用服务 2.服务端的异步实现 WCF客户端异步调用服务主要通过生成异步的代理类, ...
- WCF中,通过C#代码或App.config配置文件创建ServiceHost类
C# static void Main(string[] args) { //创建宿主的基地址 Uri baseAddress = new Uri("http://localhost:808 ...
- WCF学习之旅—WCF中传统的异常处理(十六)
WCF中的异常处理 在软件开发过程中,不可能没有异常的出现,所以在开发过程中,对不可预知的异常进行解决时,异常处理显得尤为重要.对于一般的.NET系统来说,我们简单地借助try/catch可以很容易地 ...
- 在Wcf中应用ProtoBuf替代默认的序列化器
Google的ProtoBuf序列化器性能的牛逼已经有目共睹了,可以把它应用到Socket通讯,队列,Wcf中,身为dotnet程序员一边期待着不久后Grpc对dotnet core的支持更期待着Wc ...
- ajax调用本地wcf中的post和get
我们可以通过jQuery调用本地或者远程的wcf服务,本文讲解的是对本地wcf服务的post和get调用方式. post和get到底有什么区别呢?此处不作详述. 但是,post对请求的数据格式更为严格 ...
- 在 WCF 中使用高效的 BinaryFormatter 序列化
本文将定义一个 WCF 终结点行为扩展,以在 WCF 中使用更高效的 BinaryFormatter 进行二进制序列化,并实现对是否使用传统二进制序列化功能的可配置. 介绍 实现步骤 使用方法 效果 ...
- 【WCF】WCF中的InstanceContext与ConcurrencyMode【转】
一.前言 最近忙于公司的在线升级项目,一个人要负责公司四大产品的在线升级,这四个产品是在Revit中以插件形式存在的,目前基于WCF来实现.等客户总量突破5万了,再重新用socket实现. 由于有服务 ...
- WCF初探-28:WCF中的并发
理解WCF中的并发机制 在对WCF并发机制进行理解时,必须对WCF初探-27:WCF中的实例化进行理解,因为WCF中的并发特点是伴随着服务实例上下文实现的.WCF的实例上下文模型可以通过Instanc ...
随机推荐
- keras中的Flatten和Reshape
最近在看SSD源码的时候,就一直不理解,在模型构建的时候如果使用Flatten或者是Merge层,那么整个数据的shape就发生了变化,那么还可以对应起来么(可能你不知道我在说什么)?后来不知怎么的, ...
- Android Jni(Java Native Interface)笔记
首先记录一个问题,关于如何用javah生成头文件. 为什么要生成头文件?在含有 static{ System.loadLibrary("hellojni"); } 这样代码的类下面 ...
- [调试AvantCourier的笔记]
1.manifest里不能设置target sdk 不然会出现stale error. 2.manifest里要有Internet权限 3
- C# 获取QQ群数据的实现
一,分析 1,群数据获取 当访问http://qun.qq.com/air/#mygroup我们通过Fiddler可以查看到QQ群列表是从http://qun.qq.com/air/group/min ...
- 杂项:SVN 常用方法
ylbtech-杂项:SVN 1.返回顶部 1. bin obj *.suo*.user *.csproj.user *.o *.lo *.la *.al .libs *.so *.so.[0-9]* ...
- python 去停用词
Try caching the stopwords object, as shown below. Constructing this each time you call the function ...
- 使用BFG清除git仓库中的隐私文件或大文件
使用git时间不长,在调机械臂项目的时候,由于对TwinCAT3和vs的机制不太了解,没有添加很好的忽略文件(.gitignore).造成git仓库包含了很多没有用的文件,例如vs的sdf文件,Twi ...
- 利用python数据分析panda学习笔记之基本功能
1 重新生成索引 如果某个索引值不存在就引入缺失值 from pandas import Series,DataFrame import pandas as pd import numpy as np ...
- 【Hadoop】MapReduce笔记(二):MapReduce容错,任务失败处理
典型问题:Hadoop如何判断一个任务失败?失败了怎么做? 分析:实际情况下,用户代码存在软件错误.进程崩溃.机器故障等都会导致失败.Hadoop判断的失败有不同级别类型,针对不同级别的失败有不同的处 ...
- Android 电脑投屏工具Vysor Pro介绍
Chrome的插件,直接到chrome的扩展程序里面搜索Vysor,安装即可 如何破解: C:\Users\lanlan.shi\AppData\Local\Google\Chrome\User Da ...