• WCF中的AsyncPattern


    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: }
    复制代码
    • 第一个服务方法定义中, 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 的异步模型是基于通信层支持, 并不会阻塞任何一个线程。而多线程实现依然会阻塞线程池中的异步线程。

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

  • 相关阅读:
    Xshell安装教程及Xshell安装程序集组件时出错的解决方法
    Xshell远程连接的具体操作和Xshell多会话设置小技巧
    VMware中出现物理内存不足,无法使用配置的设置开启虚拟机解决方案
    在Scrapy中如何利用Xpath选择器从HTML中提取目标信息(两种方式)
    Sublime Text编辑器配置Python解释器简易教程
    虚拟机创建后该如何获取IP地址并访问互联网实用教程
    关于Scrapy爬虫项目运行和调试的小技巧(下篇)
    Spring的xml和注解对比
    Spring5.X的注解配置项目
    Spring的AOP快速实现通用日志打印
  • 原文地址:https://www.cnblogs.com/raohuagang/p/3553570.html
Copyright © 2020-2023  润新知