C#中的异步多线程13 回调

不同于等待直到结束和轮询,回调模式下一但初始线程发起了异步方法,就自己管自己了,不再考虑同步。当异步方法调用结束后,系统调用一个用户自定义的方法来处理结果,并且调用委托的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

原文地址:https://www.cnblogs.com/NicolasLiaoran/p/12964100.html