加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

使用异步方式调用WebService

发布时间:2020-12-17 02:31:22 所属栏目:安全 来源:网络整理
导读:在很多情况下我们可能都要使用异步调用WEBService。使用异步的好处是非阻塞方式进行的。当然也增加一定的编程难度。使用异步编程,我们可以实现对远程服务的调用,查询调用状态,或取消调用等功能。 我们以代码实例为例来解说 首先使用VS2k3建立一个WEBSERVI

在很多情况下我们可能都要使用异步调用WEBService。使用异步的好处是非阻塞方式进行的。当然也增加一定的编程难度。使用异步编程,我们可以实现对远程服务的调用,查询调用状态,或取消调用等功能。

我们以代码实例为例来解说
首先使用VS2k3建立一个WEBSERVICE ,假设是一个提供股票信息的服务。这里我处理的比较简单,仅是模拟一下服务调用需要很长的时间。
namespace StockService
{
?/// <summary>
?/// Service1 的摘要说明。
?/// </summary>
?public class StockPrice : System.Web.Services.WebService
?{
? public StockPrice()
? {
?? //CODEGEN: 该调用是 ASP.NET Web 服务设计器

所必需的
?? InitializeComponent();
? }

? #region 组件设计器生成的代码
?
? //Web 服务设计器所必需的
? private IContainer components = null;
???
? /// <summary>
? /// 设计器支持所需的方法 - 不要使用代码编辑器修改
? /// 此方法的内容。
? /// </summary>
? private void InitializeComponent()
? {
? }

? /// <summary>
? /// 清理所有正在使用的资源。
? /// </summary>
? protected override void Dispose( bool disposing )
? {
?? if(disposing && components != null)
?? {
??? components.Dispose();
?? }
?? base.Dispose(disposing);?
? }
?
? #endregion

? [WebMethod]
? public double getStockPrice(String stockSymbol)
? {
?? //在这里我们进行模拟处理,线程暂停5秒
?? Thread.Sleep(5000);
?? return new Random().NextDouble() + 15.0;
? }
? [WebMethod]
? public double getStockPrice1(String stockSymbol)
? {
?? //在这里我们进行模拟处理,线程暂停5秒
?? Thread.Sleep(5000);
?? return new Random().NextDouble() + 15.0;
? }
? [WebMethod]
? public double getStockPrice2(String stockSymbol)
? {
?? //在这里我们进行模拟处理,线程暂停5秒
?? Thread.Sleep(5000);
?? return new Random().NextDouble() + 15.0;
? }

?}
}


然后我们建立一个WINFORM程序来充当客户端调用刚才建立的WEBSERVICE。这里我们有很多种方式来实现异步调用(包括自己建立一个线程来调用服务,当服务完成后,使用delegate来实现事件的回调)。这种方法我们先排除掉。因为当你添加一个WEB引用到本地工程时,代理类里已实现了异步调用的代码。
?public class Form2 : System.Windows.Forms.Form
?{
? private localhost.StockPrice m_stockService;
? private IAsyncResult m_handle;
? private System.Windows.Forms.Button button1;
? private System.Windows.Forms.Button button2;
? private System.Windows.Forms.Button button3;
? private System.Windows.Forms.Button button4;
? private System.Windows.Forms.TextBox messageBox;
? private System.Windows.Forms.Button button5;
? private System.Windows.Forms.Button button6;?

? /// <summary>
? /// 必需的设计器变量。
? /// </summary>
? private System.ComponentModel.Container components = null;

? public Form2()
? {
?? //
?? // Windows 窗体设计器支持所必需的
?? //
?? InitializeComponent();

?? //
?? // TODO: 在 InitializeComponent 调用后添加任何构造函数代码
?? //
? }

? /// <summary>
? /// 清理所有正在使用的资源。
? /// </summary>
? protected override void Dispose( bool disposing )
? {
?? if( disposing )
?? {
??? if(components != null)
??? {
???? components.Dispose();
??? }
?? }
?? base.Dispose( disposing );
? }

? #region Windows 窗体设计器生成的代码
? /// <summary>
? /// 设计器支持所需的方法 - 不要使用代码编辑器修改
? /// 此方法的内容。
? /// </summary>
? private void InitializeComponent()
? {
?? this.messageBox = new System.Windows.Forms.TextBox();
?? this.button1 = new System.Windows.Forms.Button();
?? this.button2 = new System.Windows.Forms.Button();
?? this.button3 = new System.Windows.Forms.Button();
?? this.button4 = new System.Windows.Forms.Button();
?? this.button5 = new System.Windows.Forms.Button();
?? this.button6 = new System.Windows.Forms.Button();
?? this.SuspendLayout();
?? //
?? // messageBox
?? //
?? this.messageBox.Location = new System.Drawing.Point(16,8);
?? this.messageBox.Multiline = true;
?? this.messageBox.Name = "messageBox";
?? this.messageBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
?? this.messageBox.Size = new System.Drawing.Size(656,320);
?? this.messageBox.TabIndex = 0;
?? this.messageBox.Text = "";
?? //
?? // button1
?? //
?? this.button1.Location = new System.Drawing.Point(24,344);
?? this.button1.Name = "button1";
?? this.button1.TabIndex = 1;
?? this.button1.Text = "调用";
?? this.button1.Click += new System.EventHandler(this.button1_Click);
?? //
?? // button2
?? //
?? this.button2.Location = new System.Drawing.Point(128,344);
?? this.button2.Name = "button2";
?? this.button2.TabIndex = 2;
?? this.button2.Text = "轮询";
?? this.button2.Click += new System.EventHandler(this.button2_Click);
?? //
?? // button3
?? //
?? this.button3.Location = new System.Drawing.Point(240,344);
?? this.button3.Name = "button3";
?? this.button3.TabIndex = 3;
?? this.button3.Text = "中止";
?? this.button3.Click += new System.EventHandler(this.button3_Click);
?? //
?? // button4
?? //
?? this.button4.Location = new System.Drawing.Point(352,344);
?? this.button4.Name = "button4";
?? this.button4.Size = new System.Drawing.Size(96,23);
?? this.button4.TabIndex = 4;
?? this.button4.Text = "等待异步操作";
?? this.button4.Click += new System.EventHandler(this.button4_Click);
?? //
?? // button5
?? //
?? this.button5.Location = new System.Drawing.Point(464,344);
?? this.button5.Name = "button5";
?? this.button5.Size = new System.Drawing.Size(120,23);
?? this.button5.TabIndex = 5;
?? this.button5.Text = "一次调用三个服务";
?? this.button5.Click += new System.EventHandler(this.button5_Click);
?? //
?? // button6
?? //
?? this.button6.Location = new System.Drawing.Point(608,344);
?? this.button6.Name = "button6";
?? this.button6.TabIndex = 6;
?? this.button6.Text = "回调处理";
?? this.button6.Click += new System.EventHandler(this.button6_Click);
?? //
?? // Form2
?? //
?? this.AutoScaleBaseSize = new System.Drawing.Size(6,14);
?? this.ClientSize = new System.Drawing.Size(696,477);
?? this.Controls.Add(this.button6);
?? this.Controls.Add(this.button5);
?? this.Controls.Add(this.button4);
?? this.Controls.Add(this.button3);
?? this.Controls.Add(this.button2);
?? this.Controls.Add(this.button1);
?? this.Controls.Add(this.messageBox);
?? this.Name = "Form2";
?? this.Text = "Form2";
?? this.Load += new System.EventHandler(this.Form2_Load);
?? this.ResumeLayout(false);

? }
? #endregion

? private void Form2_Load(object sender,System.EventArgs e)
? {
?
? }

? //你调用BegingetStockPrice()后得到一个具有IAsyncResult界面的对象。
? //它提供了IsCompleted的属性。当这个值为"True"的时候,
? //你就可以通过调用EndgetStockPrice()来拿到函数运行的结果。
? //更重要的是,你可以在异步调用的时候"放弃Abort"调用。
? //下面的程序段是用3个"按钮(Button)"来示意如何使用异步调用,检查调用是否结束以及放弃调用。

? //异步调用WebMethod
? private void button1_Click(object sender,System.EventArgs e)
? {
?? m_stockService = new localhost.StockPrice();
?? m_handle = m_stockService.BegingetStockPrice("IBM",null,null);
?? messageBox.Text += "正在调用WEB服务." + System.Environment.NewLine;

? }
? //检查异步调用是否完成。如果完成的话,就取出调用结果
? private void button2_Click(object sender,System.EventArgs e)
? {
?? if(m_handle==null)
?? {
??? messageBox.Text += "没有服务被调用!"+System.Environment.NewLine;
??? return;
?? }
?? if(m_handle.IsCompleted == false)
??? messageBox.Text += "服务正在调用中"? + System.Environment.NewLine;
?? else
?? {
??? double price = m_stockService.EndgetStockPrice(m_handle);
??? messageBox.Text += "金额为: " + price + System.Environment.NewLine;
?? }

? }

? //放弃异步调用
? private void button3_Click(object sender,System.EventArgs e)
? {
?? if(m_handle!=null)
?? {
??? WebClientAsyncResult result = (WebClientAsyncResult)m_handle;
??? result.Abort();
??? m_handle = null;
?? }
?? messageBox.Text += "调用服务被用户终止" + System.Environment.NewLine;

? }

? //使用WaitHandle
? //你调用BegingetStockPrice()后得到一个具有IAsyncResult界面的对象。
? //它提供了AsyncWaitHandle的属性。调用它的WaitOne()函数可以使程序被阻拦直到另外一个线程函数调用完成。
? //之后程序将继续往下执行。
? private void button4_Click(object sender,System.EventArgs e)
? {
?? if(this.m_stockService ==null)
??? m_stockService = new localhost.StockPrice();
?? m_handle = m_stockService.BegingetStockPrice("IBM",null);
?? messageBox.Text? += "正在调用服务" + System.Environment.NewLine;
?? m_handle.AsyncWaitHandle.WaitOne();
?? double price = m_stockService.EndgetStockPrice(m_handle);
?? messageBox.Text += "金额为: " + price + System.Environment.NewLine;??

? }

? //从现象上看,和同步调用相比你并没有得到好处。程序等待的时候仍然处于"挂起"状态。
? //但是在有些情况下,"等待"还是有它的特色的。
? //比如说你可以连续调用三个WebMethod,如果每个函数费时5秒,
? //那么使用同步的话总共会使用15秒钟。但如果使用异步的话,你可能只要等待5秒钟。
? //当然这要使用WaitHandle提供的WaitAll()函数。如下所示:
? //一次调用三个服务
? private void button5_Click(object sender,System.EventArgs e)
? {
??
?? if(this.m_stockService ==null)
??? m_stockService = new localhost.StockPrice();
?? IAsyncResult[] handles = new IAsyncResult[3];
?
?? messageBox.Text? += "一次调用三个服务:开始时间为"+DateTime.Now.ToString() + System.Environment.NewLine;
?? handles[0] = m_stockService.BegingetStockPrice("IBM",null);
?? handles[1] = m_stockService.BegingetStockPrice1("MS",null);
?? handles[2] = m_stockService.BegingetStockPrice2("SUN",null);
??
?? WaitHandle[] WaitHandles ={
??? handles[0].AsyncWaitHandle,
??? handles[1].AsyncWaitHandle,
??? handles[2].AsyncWaitHandle};
?
?? //函数被阻拦,直到3个函数都执行完毕。WaitAny()函数情况类似,但有一个函数完成后
?? //程序就解阻,继续往下执行
?? WaitHandle.WaitAll(WaitHandles);
?? messageBox.Text+="调用完成时间为:"+DateTime.Now.ToString()+ System.Environment.NewLine;
?? double[] prices = new double[3];
?? for(int i=0;i<3;i++)
?? {
??? prices[i] = m_stockService.EndgetStockPrice(handles[i]);??
??? messageBox.Text += "金额为: " + prices[i] +
???? System.Environment.NewLine;
?? }
?? messageBox.Text? += "调用三个服务完毕:" + System.Environment.NewLine;
? }

? //看到现在,你可能还没有感到满意。因为你异步调用了函数后,还要手工检查函数是否执行完毕,
? //或者要处于等待状态。能否让函数完成后,自动显示结果或是做其它操作呢?
? //答案是"能"的。回调函数就是做这种事情的。
? private void button6_Click(object sender,System.EventArgs e)
? {
?? if(this.m_stockService ==null)
??? m_stockService = new localhost.StockPrice();
?? //生成回调函数
?? AsyncCallback cb = new AsyncCallback (this.callback);
?? m_stockService.BegingetStockPrice("IBM",cb,DateTime.Now);
?? messageBox.Text? += "远程服务被调用" + System.Environment.NewLine;

? }
? private void callback(IAsyncResult handle)
? {
?? double price = m_stockService.EndgetStockPrice(handle);
?? lock(this)
?? {
??? messageBox.Text += "金额为: " + price + ". 请求时间: " +
???? handle.AsyncState.ToString() + ",结束时间: " +
???? DateTime.Now.ToString() +
???? System.Environment.NewLine;
?? }
? }
?}

?


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/greystar/archive/2005/02/02/278059.aspx

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读