深入学习Web Service系列----异步开发模式

概述

在本篇随笔中,通过一些简单的示例来说一下Web Service中的异步调用模式。调用Web Service方法有两种方式,同步调用和异步调用。同步调用是程序继续执行前等候调用的完成,而异步调用在后台继续时,程序也继续执行,不必等待方法处理完成而直接返回。具体的调用流程见下图:

 

对于同步调用方法而言,UI线程依赖于方法的实现,方法执行时间过长将导致UI无法及时与用户进行交互。我们知道,在Windows客户端中,每个进程都有单一的UI进程,在服务器中,可扩展性依赖于线程的使用。对于异步调用方法而言,能够及时于用户交互响应,从而提供了良好的用户体验;同时也可以改善服务器的可扩展性,将服务器与通讯问题隔离。

 

客户端异步调用方法

在客户端异步调用是完全基于Proxy的方法,异步行为最简单的模式。Visual StudioWSDL.EXE提供对它的直接支持。所以我们不必在Web服务应用程序中编写额外的代码来处理异步调用。

遍及.NET Framework的异步调用有一个基础的设计模式:Begin方法和End方法,他们分别用于开始和终止异步处理。Visual StudioWSDL.exe生成了这两种方法:

Begin<WebServiceMethodName>——该方法通知Web服务开始处理调用,并立即返回。该方法不返回Web服务调用所指定的数据类型,而是返回一种实现IasyncResult接口的数据类型。

End<WebServiceMethodName>——该方法通知Web服务返回先前启动的Web方法所生成的结果。

IasyncResult接口包含了WaitHandle类型的AsyncWaitHandle特性。这个公共接口允许用户的客户应用程序等待调用,而且,该接口将用AnyAll语义(例如WaitHandle.WaitOneWaitAnyWaitAll)作为信号通知客户应用程序。例如,如果想要客户应用程序异步等候一个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方法:

 [System.Web.Services.Protocols.SoapDocumentMethod(OneWay=true)]

示例代码:

/// <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 SoapSenderSoapRecevier

在进行本部分内容之前,我们需要安装WSE2.0WSE支持面向消息的编程,为我们提供了SoapSenderSoapReceiver基类,它能够支持发送和接收SoapEnvelopes,同时它也通过SoapClientSoapService提供了更多的事务支持。SoapSenderSoapReceiver在客户端和服务端同时实现,客户端使用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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/359525.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

navicate导出导入表数据问题

1.导出导入json&#xff0c;如下图&#xff0c;右击表点击导出向导&#xff0c;选择json导出类型&#xff0c;根据提示导出即可。 导入时&#xff0c;右击接收的表&#xff0c;点击导入向导&#xff0c;根据提示即可快速导入&#xff08;注&#xff1a;不同系统之间导出导入易…

tongweb通过控制台简单设置确认相关常用参数

1.环境版本 jdk&#xff0c;tongweb版本确认是否正确 2.检查tongweb的 license是不是永久版本&#xff0c;试用期版本到期会停止服务。 3 JVM运行编码配置-根据系统需要配置 3.1-Dfile.encodingUTF-8 编码根据系统需要配置 4. tongweb运行内存大小--根据系统需要配置 4.1一般 …

编译原理--LL(1)分析法实验C++

一、实验项目要求 1.实验目的 根据某一文法编制调试LL&#xff08;1&#xff09;分析程序&#xff0c;以便对任意输入的符号串进行分析。本次实验的目的主要是加深对预测分析LL&#xff08;1&#xff09;分析法的理解。 2.实验要求 对下列文法&#xff0c;用LL&#xff08;…

实际中进行GC调整

调优垃圾回收与任何其他性能调优活动没有什么不同。 您需要确保了解当前的情况和期望的结果&#xff0c;而不是因为对应用程序的随机部分进行调整而产生了诱惑。 通常&#xff0c;只需执行以下过程即可&#xff1a; 陈述您的绩效目标 运行测试 测量 与目标比较 进行更改并…

达梦数据库出现卡慢简单分析点

1.检查是否有锁表 查询锁表&#xff1a;select sess_id,sql_text from v$sessions sess,v$lock lck where sess.trx_idlck.trx_id and lck.blocked1; --查询僵死会话 解锁&#xff1a;根据会话ID&#xff0c;停止会话 sp_close_session(sess_id); 2.根据v$sessions,V$L…

SEL selector (二)

SEL消息机制工作原理是什么 引用下面文章&#xff1a; 我们在之前有提到,一个类就像一个 C 结构.NSObject 声明了一个成员变量: isa. 由于 NSObject 是所有类的根类,所以所有的对象都会有一个 isa 的成员变量[公共继承].而该 isa 变量指向该对象的类(图3.15)[类在Objective-C中…

mobile cpu上禁用alpha test的相关总结

因为&#xff0c;每家芯片的特性不同&#xff0c;根据向framebuffer写法的不同&#xff0c;分为tile-based的mobile cpu&#xff0c;如ImgTec PowerVR&#xff0c;ARM Mali&#xff0c;一部分老版本Qualcomm Adreno。还有标准的direct&#xff08;immediate&#xff09;的mobil…

达梦定时迁移数据

1. 生成迁移源代码 1.1 启动DM迁移工具&#xff08;bin/dts.exe&#xff09; 1.2 右击迁移管理空白处 -> 新建工程 1.3 展开工程 -> 右击迁移&#xff0c;新建迁移 -> 输入迁移名称&#xff0c;确认 1.4 右击迁移名称&#xff0c;打开 -> 输入源数据库连接信息&…

JSP教程–最终指南

编者注&#xff1a; JavaServer Pages&#xff08;JSP&#xff09;技术使您可以轻松创建同时包含静态和动态组件的Web内容。 JSP技术提供了Java Servlet技术的所有动态功能&#xff0c;但提供了一种更自然的方法来创建静态内容。 JSP技术的主要功能包括用于开发JSP页面的语言&…

tongweb6数据源使用中时常报空异常处理方式

1.在tongweb控制台 -> jdbc配置中设置数据源参数 1.1 勾选空闲超时&#xff0c;时间默认 1.2 勾选泄露超时时间 &#xff0c;时间为半天&#xff08;14400&#xff09; 1.3 勾选连接有效性检查、创建连接验证、获取连接验证、归还连接验证 图中设置泄露超时时间为900…

eclipse远程tomcat javaweb debug样例(windows)

1.tomcat配置可被远程debug端口参数 catalina.bat 中添加 set CATALINA_OPTS-Xdebug -agentlib:jdwptransportdt_socket,servery,suspendn,address8000 导出项目war包到tomcat/webapps/目录下 切换到tomcat/bin目录下 双击startup.bat启动运行项目 2.eclipse中启动远程debug…

ASP.NET MVC的ContentResult

ASP.NET MVC的ContentResult返回简单的纯文本内容&#xff0c;可通过ContentType属性指定应答文档类型&#xff0c;通过ContentEncoding属性指定应答文档的字符编码。一个例子来演习&#xff0c;自定义一个RwResult&#xff0c;它继承ContentResult&#xff0c;为视图象ASP.NET…

windows搜索指定目录下包含某个字符串的文件

1.打开cmd窗口 &#xff1a;winr 快捷键-> 输入cmd 回车 2.切换到被搜索的文件夹&#xff08;E:\shgwy文档\日常\更新\20220808&#xff09;下 如输入&#xff1a; cd E:\shgwy文档\日常\更新\20220808 e: 3.输入搜索命令 c:\Windows\System32\findstr.exe /s /i "wa…

IIS7日志文件位置

准备统计下页面访问量 查找IIS日志,发现在以前IIS6日志的位置&#xff0c;竟然木有找到日志... 查看下IIS设置&#xff0c;发现IIS7和6的默认日志位置不一样额... IIS 6 Log files location IIS 6中日志文件的位置 %windir%\System32\LogFiles IIS 7 Log files location IIS的日…

jwt重放攻击_4个点搞懂JWT、JWS、JWE

1.JWT是何物&#xff0c;有哪些常用的场景JWT(json web token)是设计一种简洁&#xff0c;安全&#xff0c;无状态的token的实现规范rfc7519&#xff0c;通常用于网络请求方和网络接收方之间的网络请求认证。jwt的常用场景1.1: restful api接口的无状态认证, 在传统的web应用中…

Verification Mind Games---how to think like a verifier像验证工程师一样思考

1. 有效的验证需要验证工程师使用不同于设计者的思维方式思考问题。具体来说&#xff0c;验证更加关心在严格遵循协议的基础上发现设计里面的bug&#xff0c;搜索corner cases&#xff0c;对设计的不一致要保持零容忍的态度。mindset&#xff1a;一套人们应该持有的确定的态度&…

discuz安装_手动搭建 Discuz! 论坛

一、搭建LAMP环境安装软件(Apache、MariaDB、PHP)yum install httpd php php-fpm php-mysql mariadb mariadb-server -y2.启动服务systemctl start httpdsystemctl start mariadbsystemctl start php-fpm3.安装后首次启动mariadb设置mysql_secure_installation4.登录 MariaDB&a…

蓝桥杯 1223 第 2 场 小白入门赛

蓝桥小课堂-平方和 模拟 1 2 2 2 3 2 ⋯ n 2 n ⋅ ( n 1 ) ⋅ ( 2 n 1 ) 6 1^22^23^2\cdotsn^2\dfrac{n\;\cdot\;(n 1)\;\cdot\;(2n1)}{6} 122232⋯n26n⋅(n1)⋅(2n1)​。 write(n * (n 1) * (n * 2 1) / 6);房顶漏水啦 m a x ( 最大的行 − 最小的行 , 最大的列 −…

jar包是什么意思_面试难度五颗星:JVM有Full GC,为什么还会 OutOfMemoryError?

点击上方蓝色“后端面试那些事儿”&#xff0c;选择“设为星标”学最好的别人&#xff0c;做最好的我们来源&#xff1a;R 大zhihu.com/question/38511221问题&#xff1a;R大回复平时有逛知乎的习惯&#xff0c;一般对JVM相关话题比较感兴趣。偶然看到这个问题&#xff0c;结果…

系统执行sql很慢达梦工具执行很快的简单解决方式

现象描述&#xff1a;系统功能查询很慢&#xff0c;拷贝查询sql到达梦工具中执行速度很快 1.问题分析&#xff1a; 达梦SQL执行耗时异常问题排查_qq_39693441的博客-CSDN博客_sql耗时分析 2.解决方式1&#xff1a; 在程序sql中拼接随机数如&#xff1a; select /*动态随机数*…