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异步的一些总结,如有不对,欢迎指正。

转载于:https://www.cnblogs.com/Lawson/archive/2012/04/23/2467274.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值