不同于等待直到结束和轮询,回调模式下一但初始线程发起了异步方法,就自己管自己了,不再考虑同步。当异步方法调用结束后,系统调用一个用户自定义的方法来处理结果,并且调用委托的EndInvoke方法。这个用户自定义的方法就是回调方法。
BeginInvoke的最后两个参数由回调函数使用。
1、最后两个中的第一个参数callback,是回调方法的名字
2、第二个参数state,可以使null或要传入回调方法的一个对象的引用。我们可以通过使用IAsyncResult参数的AsyncState属性来获取这个对象,参数类型是object。
callback:
回调方法的签名和返回类型必须和AsyncCallBack委托类型所描述的形式一致。它需要方法接受一个IAsyncResult作为参数并且返回类型为void。由于callback参数是AsyncCallBack类型的委托,所以也可以以委托的形式提供,所以可以以new AsyncCallBack(Method)这种使用回调方法创建委托的形式,也可以直接用回调方法的名字。
回调方法中的EndInvoke:
在回调方法中,代码调用委托的EndInvoke方法来处理异步方法执行后的输出。要调用委托的EndInvoke方法,就必须直到委托对象的引用,但它在初始线程中而不在开启的线程中。
若不使用BeginInvoke的state参数做其他用途,可以使用它发送委托的引用给回调方法。
然后可以从发送给方法作为参数的IAsyncResult对象中提取出委托的引用。
1、给回调方法的参数只有一个,就是刚结束的异步方法的IAsyncResult接口的引用。IAsyncResult接口对象在内部就是AsyncResult类的对象。
2、尽管IAsyncResult接口没有委托对象的引用,而封装他的AsyncResult类对象却有委托对象的引用。
3、有了类对象的引用,就可以调用了类的AsyncDelegate属性并且把它转化为合适的委托类型,这样就得到了委托引用,可以用它来调用EndInvoke。
示例:
class Program { delegate long Mydel(int first, int second); static long Sum(int x,int y) { Console.WriteLine("Inside Sum"); Thread.Sleep(100); return x + y; } static void CallWhenDone(IAsyncResult iar) { Console.WriteLine("Inside CallWhenDone"); AsyncResult ar = (AsyncResult)iar; Mydel del = (Mydel)ar.AsyncDelegate; long result = del.EndInvoke(iar); Console.WriteLine("The result is :{0}", result); } static void Main(string[] args) { Mydel del = new Mydel(Sum); Console.WriteLine("Before beginInvoke"); IAsyncResult iar = del.BeginInvoke(3, 5, new AsyncCallback(CallWhenDone), null); Console.WriteLine("Doing more work in Main"); Thread.Sleep(500); Console.WriteLine("Done with Main. Exiting"); Console.ReadLine(); } }
输出:
Before beginInvoke
Doing more work in Main
Inside Sum
Inside CallWhenDone
The result is :8
Done with Main. Exiting