.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就可以了,分如下几步来完成:

1. 定义我们自己的AsyncCompletedEventArgs
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;
        }
    }
}
2. 在Helper类里面定义event
public event EventHandler<CallCompletedEventArgs> CallCompleted;
3. 在CallBack中触发这个事件
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/

本文基于 署名 2.5 中国大陆 许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名 hackerzhou 并包含 原文链接
本文暂时还没有评论,你可以抢沙发哟。

发表评论