异步是一个庞大的话题,但总的来说,我认为它有不阻塞当前请求线程、提高吞吐量等作用。
对于服务端和客户端互相调用的程序,我认为异步可以分为客户端异步、服务端异步,并且他们异步操作互不影响。
从是否等待来看,我觉得可以分为等待异步方式和不等待的异步方式。
异步代码编写上,主要有两种方式: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直接开子线程,可以和主调用线程异步执行。
3、
Begin[WebMethodName]异步调用,End[WebMethodName]方式回调。
4、
[WebMethodName]Completed+=委托回调,[WebMethodName]Async异步方式调用。
对于winform程序,常用的还有BackgroundWorker组件来异步执行任务。
WebService服务端异步主要包括如下:
[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引用
图一
实际它内部是通过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,执行后如:
图三
图四
异步示例
下面贴下服务端异步方式的示例代码:
[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";
connection.open();
IAsyncResult ir = command.BeginExecuteReader(cb,command,System.Data.CommandBehavior.CloseConnection);
return ir;
}
[WebMethod]
public string EndServerAsyncHelloWorld(IAsyncResult ir)
{
StringBuilder sb = new StringBuilder();
省略后面代码,这里看到BeginXXX和EndXXX属性方法字段都有制定格式,比如begin里后面两个为:AsyncCallback cb,object state,分别为回调函数和主调函数和回调函数之间的传地址,比如这里传递的是sqlCommand。并且对于客户端,它发现的方法只为ServerAsyncHelloWorld了。
从上面代码可以看出,WebService服务端异步只是一个壳子,具体怎么异步还需要内部的内容执行异步调用。如果WebMethod不标注为异步调用方式,内部调用异步代码,实际请求会消耗更多的CLR线程来执行异步,或造成请求线程的阻塞等待。
对于回调函数,比如ADO.NET操作它会占用1个工作线程,但对于委托异步Remoting等会占用1个IO线程,如需要对线程更好控制的情境,需要注意这些地方。
本文是自己对WebService异步的一些总结,如有不对,欢迎指正。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。