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. 【转】看C++文档的小知识

    转载:http://www.ggv.com.cn/forum/clib/ctype/isspace.html 函数isspace 原型:extern int isspace(int c);    用法 ...

  2. BZOJ_3680_吊打XXX_模拟退火

    BZOJ_3680_吊打XXX_模拟退火 Description gty又虐了一场比赛,被虐的蒟蒻们决定吊打gty.gty见大势不好机智的分出了n个分身,但还是被人多势众的蒟蒻抓住了.蒟蒻们将 n个g ...

  3. Java笔记(十)

    正则表达式: 符合一定规则的表达式,用于专门操作字符串. 对QQ号码进行校验,要求:5-11位,0不能开头,只能是数字. public class Demo{ public static void m ...

  4. Dubbo原理与框架设计

    Dubbo是常用的开源服务治理型RPC框架,在之前osgi框架下不同bundle之间的方法调用时用到过.其工作原理和框架设计值得开源技术爱好者学习和研究. 一.Dubbo的工作原理 调用关系说明 服务 ...

  5. ubuntu 下串口调试工具 minicom安装与配置

    检查系统是否支持USB转串口: lsmod | grep usbserial 如果有usbserial,说明系统支持USB转串口. 识别串口设备: 插上USB转串口,在终端输入命令: #dmesg | ...

  6. CodeForces 1109E. Sasha and a Very Easy Test

    题目简述:给定$m \leq 10^9+9$,维护以下操作 1. "1 l r x":将序列$a[l], a[l+1], \dots, a[r]$都乘上$x$. 2. " ...

  7. ShutdownHook作用

    源地址:http://kim-miao.iteye.com/blog/1662550 void java.lang.Runtime.addShutdownHook(Thread hook) 该方法用来 ...

  8. PHP实用小程序(七)

    <? //用COOKIE保存投票人的投票记录 if($vote && !$already_voted) SetCookie("already_voted",& ...

  9. myeclipse 重新关联项目和svn

    有时候重装了svn或重新定义了WorkSpaces,原项目和svn没关联了 那么 右击要提交的项目 在弹出的菜单依次:Team -->share project 在弹出的对话框里填入SVN的地址 ...

  10. C++类静态变量的一种使用特例

    不同进程里的数据默认情况下是互不影响的. 静态变量是属于类本身的,它的所有实例可以共享这个静态变量,但是有个先天条件就是在同一个进程的情况下!!