今天学习webservice的异步调用。找了很多都是说会在客户端生成的Proxy类中会生成Begin<方法名>和End<方法名>,然后在这两个方法之间调用自己的代码的方式实现异步操作。
但是,在客户端的Proxy类中没有这样的方法,相反的却有<方法名>Async的方法。这个是不是新的异步调用新的实现方式呢?于是网上找了找发现了两篇很有价值的博文。
一篇引用自http://book.51cto.com/art/200906/129768.htm,是李天平的。
文中讲了两种异步调用的方法。一种是用后台线程直接调用webservice。webservice本身没有什么不同,就是最直接的调用。异步主要是通过后台线程(BackgroundWorker,仅WinForm中调用)实现。
文中代码引用如下:
2 {
3 BackgroundWorker backgroundworker = new BackgroundWorker();
4 // 注册具体异步处理的方法
5 backgroundworker.DoWork += new DoWorkEventHandler(back_DoWork);
6 // 注册调用完成后的回调方法
7 backgroundworker.RunWorkerCompleted +=
8 new RunWorkerCompletedEventHandler(back_RunWorkerCompleted);
9 // 这里开始异步调用
10 backgroundworker.RunWorkerAsync();
11 // 调用服务的同时客户端处理并不停止
12 ChangeProcessBar();
13 }
14 // 完成事件
15 void back_RunWorkerCompleted( object sender, RunWorkerCompletedEventArgs e)
16 {
17 if (e.Error != null )
18 throw e.Error;
19 progressBar1.Value = progressBar1.Maximum; // 调用完成了,把客户端进度条填充满
20 string price = e.Result.ToString(); // 获取处理结果
21 MessageBox.Show( " 调用完成。价格是: " + price); // 显示从服务器获取的结果值
22 }
23 // 调用方法
24 void back_DoWork( object sender, DoWorkEventArgs e)
25 {
26 // Web Service代理类
27 ProductService.LTPService service = new ProductService.LTPService();
28 // 调用Web方法GetClass1,将结果赋值给DoWorkEventArgs的Result对象
29 e.Result = service.GetProductPrice( " 001 " );
30 }
进度条显示函数:
2 // 界面的进度条显示
3 // </summary>
4 void ChangeProcessBar()
5 {
6 for ( int i = 0 ; i < 10 ; i ++ )
7 {
8 progressBar1.Value = i;
9 System.Threading.Thread.Sleep( 500 );
10 }
11 }
第二种异步调用的方法是调用webservice内置的异步调用方式。这里主要就要调用<WebService方法名>Async方法来实现异步的。
原文代码引用如下:
2 {
3 // Web Service代理类
4 ProductService.LTPService service = new ProductService.LTPService();
5 // 这里开始异步调用
6 service.GetProductPriceAsync( " 001 " );
7 // 注册调用完成后的回调方法
8 service.GetProductPriceCompleted += new ProductService.
9 GetProductPriceCompletedEventHandler(GetProductPriceCompleted);
10 // 调用同时客户端处理不停止
11 ChangeProcessBar();
12 }
13 // 完成事件处理方法
14 void GetProductPriceCompleted( object sender, ProductService.
15 GetProductPriceCompletedEventArgs e)
16 {
17 if (e.Error != null )
18 throw e.Error;
19 progressBar1.Value = progressBar1.Maximum; // 调用完成了,把客户端进度条填充满
20 string price = e.Result.ToString(); // 获取处理结果
21 MessageBox.Show( " 调用完成。价格是: " + price); // 显示从服务器获取的结果值
22 }
另外一篇博文是冯东的,其中正好对上面讲到的内容作了些补充和总结,以及在Ajax方面做了些扩展叙述。
其中有一点,就是在Web页面的属性中添加Async="true",以使页面可以调用webservice内置的异步功能。
Web Method代码引用如下:
2 public DLL.EmployeesDataTable getEmployee()
3 {
4 DLL.EmployeesDataTable result = new DLL.EmployeesDataTable();
5 DLLTableAdapters.EmployeesTableAdapter eta = new WebServiceAsyn.DLLTableAdapters.EmployeesTableAdapter();
6 eta.FillEmployee(result);
7 return result;
8 }
客户端调用代码引用如下:
2 private AsynWebService.Service1 asynSer;
3 // 构造函数初始化 WebService引用,并为异步调用WebService设置好了结果处理函数【方法名Completed】(先这么叫吧,我也不知道怎么叫)
4 public _Default()
5 {
6 asynSer = new AsynWebService.Service1();
7 asynSer.HelloWorldCompleted += new AsynWebService.HelloWorldCompletedEventHandler(asynSer_HelloWorldCompleted);
8 asynSer.getEmployeeCompleted += new AsynWebService.getEmployeeCompletedEventHandler(asynSer_getEmployeeCompleted);
9 }
10 protected void Button1_Click( object sender, EventArgs e)
11 {
12 // 开始异步调用HelloWorld;
13 asynSer.HelloWorldAsync();
14 }
15
16 protected void asynSer_HelloWorldCompleted( object sender, AsynWebService.HelloWorldCompletedEventArgs e)
17 {
18 this .Label1.Text = e.Result.ToString();
19 }
20
21 protected void asynSer_getEmployeeCompleted( object sender, AsynWebService.getEmployeeCompletedEventArgs e)
22 {
23 this .GridView1.DataSource = e.Result;
24 this .GridView1.DataBind();
25 }
26 protected void Button2_Click( object sender, EventArgs e)
27 {
28 // 开始异步调用getEmployee
29 asynSer.getEmployeeAsync();
30 }
下面是作者给出的Ajax的异步调用和作者对这两种异步调用方式的总结:
2 var xmlHttp;
3 function createXMLHttpRequest()
4 {
5 if (window.ActiveXObject)
6 {
7 xmlHttp = new ActiveXObject( " Microsoft.XMLHTTP " );
8 }
9 else if (window.XMLHttpRequest)
10 {
11 xmlHttp = new XMLHttpRequest();
12 }
13 }
14
15 function requestStart()
16 {
17 if (document.getElementById( " tbx1 " ).value.length <= 4 )
18 {
19 alert( " 用户名的长度要求大于4个字符! " );
20 return false ;
21 }
22 document.getElementById( " sp1 " ).innerText = " Loding " ;
23 var url = " default.aspx?userName= " + document.getElementById( " tbx1 " ).value;
24 createXMLHttpRequest(); // 创建XMLHttpRequest对象
25 xmlHttp.onreadystatechange = callBack; // 为XMLHttpRequest对象指定结果处理函数
26 xmlHttp.open( " GET " ,url); // 打开链接
27 xmlHttp.send( null ); // 发送请求
28 }
29 // 结果处理函数
30 function callBack()
31 {
32 if (xmlHttp.readyState == 4 )
33 {
34 document.getElementById( " sp1 " ).innerText = xmlHttp.responseText;
35 }
36 }
37 < / script>
作者给出的总结
1:Ajax需要创建XMLHttpRequest对象,Asp.Net需要实体化WebService代理类对象
2:XMLHttpRequest 对象需要指定结果处理函数,Asp.Net也需要指定结果处理函数
3:XMLHttpRequest的结果处理函数必须在请求发送之前设置,Asp.Net同样也是需要在 方法被调用之前设置好结果处理函数
作者还提到了一些Flex中的异步调用webservice的知识,用兴趣的同学可以到作者的原文中查看。
引用博文:
http://book.51cto.com/art/200906/129768.htm
http://www.cnblogs.com/interboy/archive/2007/04/06/702594.html