C#语言中的异步方法调用

开发者在线 Builder.com.cn 更新时间:2002-04-03作者:ZDNET CHINA 特稿 来源:

BeginResolve方法和IAsyncResult

为了不阻塞程序的执行(就像第一个例子那样),你可以选择使用Resolve方法的异步版本:BeginResolve。这个方法的用法如下:

public static IAsyncResultBeginResolve(
string hostName,
AsyncCallbackrequestCallback,
object stateObject
);

BeginResolve方法和其同步版本一样接受同样的参数hostName,不过增加了异步设计模式下所需要的另两个参数:requestCallback和stateObject参数。我们很快就会讨论到这两个参数,但是首先让我们注意一下返回值:一个IAsyncResult接口。

当你异步调用某个方法的时候,在被调用方法有机会完成任务以前(甚至有时在刚调用的时候)方法调用就会很快地返回程序。按照定义,BeginResolve方法不会返回IPHostEntry对象,相反,它会返回一个等待对象,这就是IAsyncResult接口,之后可以使用它来检索方法调用的结果。

IAsyncResult 接口的定义如下:
public interface IAsyncResult {
object AsyncState
WaitHandleAsyncWaitHandle
boolCompletedSynchronously
boolIsCompleted
}

 

该接口的第一个属性是AsyncState,它会返回传递给BeginResolve方法的stateObject参数同样的对象。这个参数值没有受到任何限制。它可以是程序想用来追踪这个特定方法调用的任何东西。被调用方法无论在什么方式下都不会使用或操作它。

IAsyncResult接口的第二个属性是AsyncWaitHandle,你的程序可以用它来等待方法完成其任务,具体做法是把它传递给WaitHandle类的方法WaitAll、WaitOne或WaitAny之一即可。如果你正在平行发送若干异步方法调用、希望它们都能保证在继续你自己程序的工作之前完成,那么这个属性就会非常管用,如果程序的继续操作依赖于以上这些调用中的一个或者多个结果,这个属性的用处就更大了。

该接口的第3个属性是CompletedSynchronously,它返回一个布尔值,表示方法是否能在BeginResolve方法返回的时候完成任务。

第4个属性是IsCompleted,它也返回一个布尔值,表示方法所要完成的任务是否已经完成了。如果你正在使用一种查询机制来确定异步调用是否完成其任务,那么这个属性此刻就能派上用场了。

实际上,发起和完成.NET异步调用有4种方案可供你选择。首先是采用查询(IsCompleted属性),其次是利用回调函数(在下面讨论),第三是采用AsyncWaitHandle来等待方法调用的完成,最后,你还可以自己调用EndXXXX,当BeginXXXX方法返回IAsyncResult之时你且尽管等着调用完成即可。这最后两种技术之间的差别在于,如果你采取等待自己(使用AsyncWaitHandle)这一措施,那么你能在一定超时设置基础之上随时“唤醒”,同时在这一时刻决定你是否确实想再等待下去。

EndResolve方法和AsyncCallback

完成异步方法调用的方法之一是给BeginXXXX方法提供一个AsyncCallback函数。这个函数的语法如下:

public delegate void AsyncCallback(
       IAsyncResultar
);

在程序中加入以上的代码同时创建一个AsyncCallback函数指向该方法,你就可以让异步方法调用通知你的程序它在什么时候能完成了自己的任务处理。下列代码片段说明该如何采用回调函数调用Dns类的BeginResolve方法:
AsyncCallback callback = new AsyncCallback(GetResult);
IAsyncResultar = Dns.BeginResolve("10.10.14.2", callback, null);
// 以上任务完成之时尽管做其他工作。


当BeginResolve方法完成任务并且返回一个IPHostEntry对象的时候,它会调用传递给它的回调函数让我们获得结果。下列代码显示了程序中实现的GetResult 方法:

private void GetResult(IAsyncResultar) {
IPHostEntry host = Dns.EndResolve(ar);
}


在得到了解析请求的IP地址后,Dns类调用GetResult方法,把最初调用所返回的同样IAsyncResult接口传递给BeginResolve。这样我们就可以用该参数调用EndResolve来获得调用结果。

总结

在.NET下你既可以使用同步也可以使用异步方法,这完全是你的编程自由,不过,在很多情况下采用异步途径往往更有效率。

责任编辑:超凡

用户评论

  • 用户名
  • 评论内容