zoukankan      html  css  js  c++  java
  • WebService异步

    异步是一个庞大的话题,但总的来说,我认为它有不阻塞当前请求线程、提高吞吐量等作用。
    对于服务端和客户端互相调用的程序,我认为异步可以分为客户端异步、服务端异步,并且他们异步操作互不影响。
    从是否等待来看,我觉得可以分为等待异步方式和不等待的异步方式。
    异步代码编写上,主要有两种方式:APM Asynchronouse Programming Model,EAP Event-base Asynchronous Pattern。它们分别是BeginXXX,EndXXX和基于事件的XXXCompleted,XXXAsync的异步方式。
    除了创建线程等方式的异步,如果和CPU并行执行任务,是需要硬件支持的,大多硬件都提供了DMA功能,当硬件在DMA模式下,CPU只须向DMA控制器下达指令,让DMA控制器来处理数据的传送,数据传送完毕再用中断的方式反馈给CPU,这块更专业的解释需要参考其他文章资料。封装后对于.net程序的异步,一般都是通过回调的方式通知异步完成了。
    WebService异步
    我认为WebService客户端异步主要包括如下:
    1、 用线程Thread直接开子线程,可以和主调用线程异步执行。
    2、 用线程池ThreadPool开后台线程,和主调用线程异步执行。
    3、 Begin[WebMethodName]异步调用,End[WebMethodName]方式回调。
    4、 [WebMethodName]Completed+=委托回调,[WebMethodName]Async异步方式调用。
    对于winform程序,常用的还有BackgroundWorker组件来异步执行任务。
    WebService服务端异步主要包括如下:
    1、 配置webmethod为One-way方式,即在WebMethod添加属性为:
    [System.Web.Services.Protocols.SoapDocumentMethod(OneWay = true)],对于One-way方式,服务端要求是void返回类型,客户端调用后就不关心后续执行是否正确或异常了,直接返回客户端,因此我自己认为可以算服务端配置的一个异步。但经过我的测试,发现One-way方式始终要增加一个windows线程来处理,并且这个线程为1个工作线程,因此最好不要大量使用。
    2、 Begin[WebMethodName],End[WebMethodName]方式,服务端配置和客户端配置不一样,服务端配置BeginXXX,EndXXX方式,BeginXXX返回IAsyncReSult结果,EndXXX接受IAsyncResult为参数的方法,对于客户端,同样需要等待服务端的整个执行流程,唯一的优化是在BeginXXX和EndXXX之间释放出了一个CLR线程,可以提高并发量。对于回调函数EndXXX,它会根据不同情况占据不同的CLR线程。
    3、 服务端自己开子线程,可以立即返回客户段,也可以用信号量等待服务端执行完毕再返回,或者插入消息队列等,异步逻辑,因此我觉得泛指的异步是一个大的话题。
    WebService引用方式
    对于.Net引用webserv ice主要有两种方式:
    1、 Web引用
    在.net2.0框架下的项目,右键项目,下面即有添加Web引用,如果是高版本框架项目下,在添加服务引用下,进入高级按钮选项,有添加Web引用的按钮。如图:


    图一
    实际它内部是通过WSDL.exe程序来引用webservice,但它只能生成基于事件的异步方式,执行命令比如: 
    wsdl.exe http://localhost:4003/Service1.asmx /out:Service1.cs,执行后如:
     
    图二
    2、 服务引用
    它内部通过SvcUtil.exe程序,引用.net2.0后新增的WCF等,兼容以前web服务,比如: 
    svcutil http://localhost:4003/Service1.asmx /out:service2.cs,执行后如:
     
    图三
    WSDL和SvcUtil程序位于C:\Program Files\Microsoft SDKs\Windows\v6.0A(可能其他版本)\bin目录下,生成了cs文件后,可以通过:
    csc.exe /target:library /out:Service1.dll Service1.cs 来生成对应的dll文件。
    但是默认服务引用不会生成异步调用方式,需要在高级里勾选生成异步操作,它会生成基于事件和APM的异步调用方式,如图:
     
    图四
    异步示例
    下面贴下服务端异步方式的示例代码:
        [WebMethod]
        public IAsyncResult BeginServerAsyncHelloWorld(string str, AsyncCallback cb, object state)
        { 
                //http://lawson.cnblogs.com
        string connectionString = @"Data Source=localhost;User ID=sa;Password=1123;Asynchronous Processing=true";
                SqlConnection connection = new SqlConnection(connectionString);
                connection.Open();
                SqlCommand command = new SqlCommand(sql, connection);
                IAsyncResult ir = command.BeginExecuteReader(cb, command, System.Data.CommandBehavior.CloseConnection);
                return ir;
        }
        [WebMethod]
        public string EndServerAsyncHelloWorld(IAsyncResult ir)
        {
            StringBuilder sb = new StringBuilder();
            SqlCommand command = (SqlCommand)ir.AsyncState;
    省略后面代码,这里看到BeginXXX和EndXXX属性方法字段都有制定格式,比如begin里后面两个为:AsyncCallback cb, object state,分别为回调函数和主调函数和回调函数之间的传地址,比如这里传递的是SqlCommand。并且对于客户端,它发现的方法只为ServerAsyncHelloWorld了。
    从上面代码可以看出,WebService服务端异步只是一个壳子,具体怎么异步还需要内部的内容执行异步调用。如果WebMethod不标注为异步调用方式,内部调用异步代码,实际请求会消耗更多的CLR线程来执行异步,或造成请求线程的阻塞等待。
    对于回调函数,比如ADO.NET操作它会占用1个工作线程,但对于委托异步Remoting等会占用1个IO线程,如需要对线程更好控制的情境,需要注意这些地方。
    虽然服务端用了异步方式,对于客户端,同样可以再继续异步,它们互不影响,比如可以用基于事件异步,或APM方式的异步调用服务端异步方法。
    最后,对于WebService服务端异步方式,服务端可以操作基于IOCP的异步调用方式,异步过程中节约线程,提供并发量。对于客户端异步方式,可以不阻塞主线程,提高用户体现等。
    本文是自己对WebService异步的一些总结,如有不对,欢迎指正。
  • 相关阅读:
    IE故障修复之点击无反应
    第三十四天 我为集成平台狂(七)-步履轻盈的JQuery(五)
    《世界如此险恶,你要内心强大》读书笔记(二)
    hbase phoenix char may not be null
    堆(优先级队列) 的应用
    JVM 调优总结
    Reactor模式和NIO
    JVM调优总结 -Xms -Xmx -Xmn -Xss
    Hadoop源码分析37 RPC的线程协作
    Hadoop源码分析37 RPC的线程协作
  • 原文地址:https://www.cnblogs.com/Lawson/p/2467274.html
Copyright © 2011-2022 走看看