委托 异步

public static void after(IAsyncResult result)
{
AsyncResult async = (AsyncResult)result;
Func<string, string> func =(Func<string,string>)async.AsyncDelegate;//获取异步调用的委托对象 被传入AsyncCallback委托目标中的IAsyncnResult参数,其实是System.Runtime.Remoting.Messaging命名空间下的AsyncResult类。该类的静态属性AsyncDelegate返回了别处创建的原始异步委托的引用。
Console.WriteLine(func.EndInvoke(result));
}
static void Main(string[] args)
{
Func<string, string> func = Untity.Rollover;
AsyncCallback Callback=new AsyncCallback(Program.after);//异步完成时调用的方法
func.BeginInvoke(Console.ReadLine(), Callback, null);
Console.ReadKey();

}

我们可以发现,在Begin()和End()之间的是异步的,但是在End之后的主线程还是被阻塞了(其实是Begin完成之前,End调用线程被阻塞了)。主线程有被阻塞的可能,那么异步委托就毫无优势可言。为了让线程能够发现一部调用是否完成,IAsyncResult接口提供了IsCompleted属性。使用这个成员,调用线程在调用End之前,便能够判断异步调用是否真的完成。没有完成可以做其他事情。

 

Code
IAsyncResult iftAR = b.BeginInvoke(10, 10, null, null);

// 直到Add()方法完成,消息才会显示出来
while (!iftAR.IsCompleted)
{
Console.WriteLine("Doing more work in Main()!");
// 这里只是为了等待1秒,防止输出太多
Thread.Sleep(1000);
}

// 知道Add已经完成
int answer = b.EndInvoke(iftAR);

 

除了IsCompleted属性,接口还提供了AsyncWaitHandle属性以便实现更加灵活的阻塞控制。这个属性返回一个WaitHandle类型的实例,它有一个名为waitOne()的方法。使用这个方法可以指定等待时间。如果超时,waitOne()返回false

IAsyncResult iftAR = b.BeginInvoke(10, 10, null, null);

// 直到Add()方法完成,消息才会显示出来
while (!iftAR.AsyncWaitHandle.WaitOne(1000, true))
{
Console.WriteLine("Doing more work in Main()!");
}

// 知道Add已经完成
int answer = b.EndInvoke(iftAR);

这就像不重不断询问的方式,并不是很高效,委托还提供了另外的技术来获取异步调用结果。

 

 

AsynCallbackAsyncResult、传递自定义数据

通过轮询的方式来确定调用的方法执行是否结束,这种方式并不好。我们可以在任务完成的时候由次线程主动通知调用线程的方式。要使用这种方式,需要在BeginInvoke()时提供一个System.AsyncCallback委托的实例作为参数。只要提供了这个对象,当一部调用完成的时候,委托便会自动调用(AsyncCallback对象)指定的方法。



posted @ 2011-11-16 11:56  Rookier  阅读(353)  评论(0编辑  收藏  举报