深入学习Web Service系列----异步开发模式
概述
在本篇随笔中,通过一些简单的示例来说一下Web Service中的异步调用模式。调用Web Service方法有两种方式,同步调用和异步调用。同步调用是程序继续执行前等候调用的完成,而异步调用在后台继续时,程序也继续执行,不必等待方法处理完成而直接返回。具体的调用流程见下图:
对于同步调用方法而言,UI线程依赖于方法的实现,方法执行时间过长将导致UI无法及时与用户进行交互。我们知道,在Windows客户端中,每个进程都有单一的UI进程,在服务器中,可扩展性依赖于线程的使用。对于异步调用方法而言,能够及时于用户交互响应,从而提供了良好的用户体验;同时也可以改善服务器的可扩展性,将服务器与通讯问题隔离。
客户端异步调用方法
在客户端异步调用是完全基于Proxy的方法,异步行为最简单的模式。Visual Studio和WSDL.EXE提供对它的直接支持。所以我们不必在Web服务应用程序中编写额外的代码来处理异步调用。
遍及.NET Framework的异步调用有一个基础的设计模式:Begin方法和End方法,他们分别用于开始和终止异步处理。Visual Studio和WSDL.exe生成了这两种方法:
Begin<WebServiceMethodName>——该方法通知Web服务开始处理调用,并立即返回。该方法不返回Web服务调用所指定的数据类型,而是返回一种实现IasyncResult接口的数据类型。
End<WebServiceMethodName>——该方法通知Web服务返回先前启动的Web方法所生成的结果。
IasyncResult接口包含了WaitHandle类型的AsyncWaitHandle特性。这个公共接口允许用户的客户应用程序等待调用,而且,该接口将用Any或All语义(例如WaitHandle.WaitOne,WaitAny和WaitAll)作为信号通知客户应用程序。例如,如果想要客户应用程序异步等候一个Web方法,可调用WaitOne来处理要完成的Web服务。
一般来说,客户端异步代理方法有两种实现机制:使用同步对象和回调机制(也许你可能对用这个词不习惯,实在找不到第二个词来代替,暂且这样称呼吧)
同步对象
同步对象允许用户对Web服务的方法进行调用(使用Begin方法),然后继续处理。在后面的程序中,可以调用End方法,传递同步对象,以便得到调用结果。这种方式下,能够继续执行函数中的程序流程,而不执行回调处理。在这里调用WaitOne()方法会挂起当前线程,避免忙等待的发生,直到Web Services方法调用结束返回后,该线程才会被重新唤起。
示例代码:
/// <summary> /// 利用同步对象实现异步调用 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btn_AsyncClient_Click(object sender, System.EventArgs e) {IAsyncResult ar = wsc.BeginHello(this.txt_UserName.Text, null, null);MessageBox.Show("Continue to do some other things");ar.AsyncWaitHandle.WaitOne();strHello = wsc.EndHello(ar);this.rtb_Result.Text = strHello; }
回调机制
从本质上说,异步回调机制是委托的.NET等价物,它通过在异步操作完成时建立一个被调用的单独方法来进行工作。调用应用程序能够继续处理其他的任务,直到回调函数被调用为止。这就意味着处理已经完成了,应用程序可以正常运行了。使用同步对象不同于回调机制的区别是,当检查Web方法是否已经完成,以及检查Web方法中是否含有需要的结果时,我们无法对其进行控制,而在回调的情况中,Web方法一旦完成,这些工作就会被自动执行。
示例代码:
/// <summary> /// 显示结果 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void UpdateResult(object sender, EventArgs e) {this.rtb_Result.Text = strHello; }public void OnHelloComplete(IAsyncResult ar) {strHello = wsc.EndHello(ar);this.rtb_Result.Invoke(new EventHandler(UpdateResult)); }/// <summary> /// 用回调机制实现异步调用 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btn_CallBack_Click(object sender, System.EventArgs e) {AsyncCallback cb = new AsyncCallback(OnHelloComplete);wsc.BeginHello(this.txt_UserName.Text, cb, null); }
使用回调机制还是同步对象取决于用户所面临的具体情况。在检查异步调用是否完成时,如果愿意对处理过程进行控制,那么可以选择使用同步对象。如果觉得自己编写代码来完成对Web服务的调用,且当方法一旦执行完毕就立即由所调用的特殊函数来处理所返回的结果更适合一些,那么就更适合用回调机制。
在客户端使用异步方法调用,可以改进UI响应度,在服务器端不需要实现异步操作,对服务器来说是透明的,而且客户端能够在任何时间选择阻塞。
服务端使用Soap One-Way方法
在服务器端使用One-Way方法实现异步调用,其实质是将单项消息发送到端点。这种方式的特点是方法没有返回值,客户端方法不会从调用的服务器端方法中收到返回值;我们无法判断方法结束的时间,对于结果需要显式通知或者轮询。
在Web 服务端,我们使用[SoapDocumentMethod]定义One-Way方法:
示例代码:
/// <summary> /// One-Way方式的异步调用Set /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btn_OneWay_Click(object sender, System.EventArgs e) {wsc.SetHello(this.txt_UserName.Text); }/// <summary> /// One-Way方式的异步调用Get /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btn_onewayGet_Click(object sender, System.EventArgs e) {strHello = wsc.GetHello();this.rtb_Result.Text = strHello; }
One-Way方法不适合于下列情况:
l 方法需要对结果轮询
l 方法需要同步
服务端使用WSE SoapSender和SoapRecevier
在进行本部分内容之前,我们需要安装WSE2.0。WSE支持面向消息的编程,为我们提供了SoapSender和SoapReceiver基类,它能够支持发送和接收SoapEnvelopes,同时它也通过SoapClient和SoapService提供了更多的事务支持。SoapSender和SoapReceiver在客户端和服务端同时实现,客户端使用SoapSender发送消息,同时可选择使用SoapReceiver接收消息;服务端使用SoapReceiver接收消息,同时也可以选择使用SoapSender发送通知和回应。
示例代码:
客户端:
/// <summary>/// 自定义的消息接收类/// </summary>public class MyReceiver: SoapReceiver{public static Form1 form;private string strBody;protected override void Receive(SoapEnvelope envelope){strBody = envelope.InnerText;///注意:在进行此项之前,一定要把rtb_Result控件的属性设为Publicform.rtb_Result.Invoke(new EventHandler(UpdateBody));}void UpdateBody(object sender, System.EventArgs e){form.rtb_Result.Text = strBody;}} /**************************************************/ /// <summary> /// 用WSE实现异步调用 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button4_Click(object sender, System.EventArgs e) {wsc.FireEvent(); }
Web Service端:
private ArrayList Listeners{get{return (ArrayList)Application["Listeners"];}}[WebMethod]public void AddListener(string listener){ArrayList alist = (ArrayList)Application["Listeners"];if(alist == null)alist = new ArrayList();alist.Add(listener);Application["Listeners"] = alist;}[WebMethod]public void FireEvent(){int i;for(i = 0;i < this.Listeners.Count;i++){SoapEnvelope envelope = new SoapEnvelope();envelope.SetBodyObject("Hello World!");envelope.Context.Addressing.Action = new Action((string)(this.Listeners[i]));envelope.Context.Addressing.ReplyTo = new ReplyTo(new System.Uri((string)(this.Listeners[i])));SoapSender peerProxy = new SoapSender(new System.Uri((string)(this.Listeners[i])));peerProxy.Send(envelope);}}
服务端使用WSE 自定义SoapMSMQ传输
SoapMSMQ是一款开源软件,简化使用WSE进行MSMQ操作,下载地址:
http://www.codeproject.com/useritems/SoapMSMQ.asp
SoapMSMQ完全支持事务,具有如下特点:
l 在事务中,请求要被同步初始化
l 同步阶段排队请求,并且返回令牌
l 异步阶段处理各个事务
l 所有持有令牌的请求都保证会被处理,但可能会不成功
l 支持向客户端发送通知
对SoapMSMQ感兴趣的朋友可以下载下来后,做进一步的研究。
总结
异步方法调用改善了客户端的响应和用户体验,增加了服务端的可扩展性。当方法需要耗费大量的时间时,可以采用异步方式调用,提供系统并发处理的能力。对于异步方式的开发,我们可以有如上所述的广泛选择。
示例程序界面:
下载地址:http://files.cnblogs.com/Terrylee/AsyncDemo.rar
出处:http://www.cnblogs.com/Terrylee/archive/2005/12/05/290845.html
转载于:https://www.cnblogs.com/mq0036/p/4029497.html
深入学习Web Service系列----异步开发模式相关推荐
- [Axis2与Eclipse整合开发Web Service系列之三] 服务端返回值
前言 在前面的三篇中 [Axis2与Eclipse整合开发Web Service系列之一] 生成Web Service Client(将WSDl 转化成 Java代码) [Axis2与Eclipse整 ...
- [Axis2与Eclipse整合开发Web Service系列之二] Top-Down方式,通过WSDL逆向生成服务端(续)
前言 本篇是承接上一篇: [Axis2与Eclipse整合开发Web Service系列之二] Top-Down方式,通过WSDL逆向生成服务端 在上一篇粗略地介绍了如何使用Top-Down的方式创建 ...
- 构建安全的Xml Web Service系列之如何察看SoapMessage
上一篇文章地址:构建安全的Xml Web Service系列一之初探使用Soap头 (5-22 12:53) 要分析Xml Web Service的安全性,首先要解决的问题是我们能了 ...
- Java开发web的几种开发模式
Java开发web的几种开发模式 Java Web开发方案有多种可供选择,这里列举一些经典的开发模式进行横向比较,为Java Web的开发模式选择提供参考.除此之外还有好多方案(如Tapestry和W ...
- SharePoint Web Service系列: Add或Update其他各种类型的项
在前面,我们讨论了如何Add或Update类型为User的项.因为User类型多少比较特殊.作为SharePoint Web Service系列讨论的结束,我们将讨论各种其他类型的项如何来写. 在SD ...
- [Axis2与Eclipse整合开发Web Service系列之二] Top-Down方式,通过WSDL逆向生成服务端
开始本篇之前, 先说说 Buttom-up(从下到上)和Top-down(从上到下)的概念 这是开发WebService的两种方式. bottom-up 方式: 先创建Java Bean或EJB, 然 ...
- 构建安全的Xml Web Service系列之初探使用Soap头
Xml Web Service 从诞生那天就说自己都么都么好,还津津乐道的说internet也会因此而进入一个新纪元,可5年多来,Xml Web Service并没有像当初宣扬的那样火起来,尽管在一些 ...
- android studio访问webservice如何传递类对象报错_小白学习web service,这是最最最基础的了,只用JDK还不会吗?...
Java Web Service实践 Web Service直接翻译就是网络服务. 主要为了解决各种语言,各种系统之间不兼容,通过SOAP(简单对象访问协议)实现互联互通. 其核心就是这个SOAP,通 ...
- Web Service 系列 → 第一个 Hello Word
一.Web Service简介 1.1.Web Service基本概念 Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intrane ...
最新文章
- gcc可以编译python程序吗_gcc c语言编译流程
- opencv和HALCON坐标系的不同
- Python练习2-基本聊天程序-虚拟茶会话
- 打印二叉树的边界节点
- 20210101 Barbalat引理
- AJAX——与服务器交换数据并更新部分网页技术
- ❤️时间管理大师!我是如何规划自己的时间的?充分利用每一分一秒!❤️
- django.db.utils.OperationalError: no such column: catalogue_product.is_public
- java实现三个数字的随机组合_JAVA编程实现随机生成指定长度的密码功能【大小写和数字组合】...
- phantomjs搭建输出js渲染后的html接口
- postman断言作用及怎么使用
- 敏捷开发系列学习总结(14)——Spotify敏捷模式详解三部曲第二篇:研发过程
- Oracle查询数据库中所有的表名称
- 前端的ajax缓存,解析jquery中的ajax缓存问题
- 【运动学】基于matlab计步【含Matlab源码 524期】
- 基于PlayTennis数据集的决策树决策分析
- 【Maven由浅入深】1.maven初体验
- PDF文件如何修改密码
- 上海旅行日志 2012年7月14日
- 迅雷下载提示:应版权方要求/包含违规内容, 文件无法下载
热门文章
- sap abap开发从入门到精通_SAP开发-ABAP数据字典(锁)
- C 语言精髓之变参函数
- [渝粤教育] 江西科技师范大学 旅行社经营管理 参考 资料
- 【渝粤教育】国家开放大学2018年春季 0275-22T内科护理学 参考试题
- 蓝桥杯基础模块1:LED跑马灯
- 将matlab中数据输出保存为txt或dat格式
- Filtration, σ-algebras
- 【OFDM系列3】AWGN下基于循环前缀(CP)OFDM调制解调原理、信噪比计算及仿真(H Harada经典OFDM书籍中代码详解及更正)
- Java多线程(7)--线程池创建线程
- python哪些类型可以作为迭代器_python0.8-----set类型与迭代器