问题描述
普通调用 Web Service的方法,在Web Service执行期间客户端会一直等待服务执行完毕才能响应。从而造成客户端 UI 线程的阻塞假死现象。这时候,异步调用就显得很有用,它可以让客户端在调用Web Service时,不至于阻塞客户端的 UI线程导致假死,还可以在调用Web Service的同时做些其他的处理。
解决方案
异步调用Web Service也有几种不同的方法,这里介绍常用的两种。
第一种方法
通过利用 Backgroundworker 对象实现。BackgroundWorker 类允许你在单独的专用线程上运行操作。耗时的操作(如下载和数据库事务)在长时间运行时可能会导致用户界面(UI)似乎处于停止响应状态。如果你需要能进行响应的用户界面,而且面临与这类操作相关的长时间延迟,则可以使用 BackgroundWorker 类方便地解决问题。
代码示例:
{
BackgroundWorker backgroundworker = new BackgroundWorker();
//注册具体异步处理的方法
backgroundworker.DoWork += new DoWorkEventHandler(back_DoWork);
//注册调用完成后的回调方法
backgroundworker.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler(back_RunWorkerCompleted);
//这里开始异步调用
backgroundworker.RunWorkerAsync();
//调用服务的同时客户端处理并不停止
ChangeProcessBar();
}
//完成事件
void back_RunWorkerCompleted
{
if (e.Error != null)
throw e.Error;
progressBar1.Value = progr
string price = e.Result.To
MessageBox.Show("调用完成。
}
//调用方法
void back_DoWork(object sende
{
//Web Service代理类
ProductService.LTPService
//调用Web方法GetClass1,将
e.Result = service.GetProd
}
其中,ChangeProcessBar()方法是处理进度条控制显示的代码,用于代表其他的操作。
//<summary>
//界面的进度条显示
//</summary>
void ChangeProcessBar()
{
for (int i = 0; i < 10; i++)
{
progressBar1.Value = i;
System.Threading.Thread.Sleep(500);
}
}
第二种方法
调用 Web Service 的 WebMethod 中的 Async 方法实现。当添加完 Web Service的引用以后,会在本地生成代理类,其中,会有一个和原Web Service方法名字相同而后缀是Async的方法。
代码示例:
private void button2_Click(obj
{
//Web Service代理类
ProductService.LTPService s
//这里开始异步调用
service.GetProductPriceAsyn
//注册调用完成后的回调方法
service.GetProductPriceComp
GetProductPriceCompleted
//调用同时客户端处理不停止
ChangeProcessBar();
}
//完成事件处理方法
void GetProductPriceCompleted(object sender, ProductService.
GetProductPriceCompletedEventArgs e)
{
if (e.Error != null)
throw e.Error;
progressBar1.Value = progressBar1.Maximum; //调用完成了,把客户端进度条填充满
string price = e.Result.ToString(); //获取处理结果
MessageBox.Show("调用完成。价格是:" + price); //显示从服务器获取的结果值
}