.NET异步编程初窥——异步调用Web Service
2010-12-17 19:09 by hackerzhou虽说用.NET的时间也不短了,可是没有正儿八经的写过.NET下的异步函数,今天借着一个小项目的需要写了一个异步动态调用Web Service的Helper类。Service Reference里面也提供了异步调用的支持,用起来挺方便的,不过感觉写的太死了,每次都要引入Service Reference感觉老麻烦的。我的想法是,给出一个URL,再给出需要调用的函数名称和参数就可以返回结果。
如何调用WebService本文不赘述,主要就是发起一个请求,把相关的参数POST到WebService,然后再读取服务器返回的XML。
一个比较简单的异步调用是通过一个委托(delegate)来做的,示例代码如下:
public String Call(String method, params KeyValuePair<String, String>[] para){ //真正的工作函数 } delegate String CallHandler(String method, params KeyValuePair<String, String>[] para); public void BeginCall(String method, params KeyValuePair<String, String>[] para) { CallHandler handler = new CallHandler(Call); handler.BeginInvoke(method, para, new AsyncCallback(CallBack), "OK"); } public void CallBack(IAsyncResult asyncResult){ CallHandler handler = (CallHandler)((AsyncResult)asyncResult).AsyncDelegate; String result = handler.EndInvoke(asyncResult); //拿到了异步调用返回的结果 }
在CallBack里面拿到了调用的结果,但是很容易发现,这样还远远不够模块化,别人要用个Call函数进行异步的操作就得每次都写这样的异步框架,要是改成异步调用返回后触发某个事件,用户只要自己写一个事件处理器就可以实现异步调用,有点类似Service Reference的异步方式(先注册一个异步完成的事件处理器,然后再开始异步调用)。其实对于这个例子来说,只需要稍加修改就能够实现事件方式的异步,就是在这个Helper类里面创建一个event,然后再CallBack里自己Fire一个Event就可以了,分如下几步来完成:
public class CallCompletedEventArgs: System.ComponentModel.AsyncCompletedEventArgs { private String result; public CallCompletedEventArgs(String result, System.Exception exception , bool cancelled, object userState) : base(exception, cancelled, userState) { this.result = result; } public string Result { get { base.RaiseExceptionIfNecessary(); return result; } } }
public event EventHandler<CallCompletedEventArgs> CallCompleted;
CallCompletedEventArgs e = new CallCompletedEventArgs(result, null, false, null); if (CallCompleted != null) { CallCompleted(this, e); }
4.在调用这个Helper类的地方注册事件处理器来获取异步调用返回的结果,所以别人如果要调用这个Helper类,只需要写如下的代码就可以享受到异步调用了:
WebServicesUtil util = new WebServicesUtil( "http://localhost:54570/MPService.asmx",Encoding.UTF8); util.CallCompleted += new EventHandler<CallCompletedEventArgs>(util_CallCompleted); KeyValuePair<String, String> para1 = new KeyValuePair<string, string>("xml",""); util.BeginCall("Invoke", para1);
static void util_CallCompleted(object sender, CallCompletedEventArgs e){ Console.WriteLine("AsyncResult:"+e.Result); }
Window Phone 7的异步调用WebService的方法有些不同,不过大体框架是差不多的,由于Sliverlight的HttpWebRequest不支持同步的GetRequestStream和GetResponse调用,这两个函数都变成了异步的调用。过两天会写一下Window Phone下的实现方式以及实现了的一个在Window Phone 7下用WebService传输UI Layout和Data的简单例子。
本文代码下载地址:http://hackerzhou.googlecode.com/svn/trunk/CSharp/WebServiceAsync/