zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    基于xmpp openfire smack开发之Android客户端开发[3]
    简单工厂,抽象工厂,工厂模式三者的对照
    【独具慧眼 推荐有礼】找出您心中的技术大牛 活动開始啦!
    ZOJ 3201
    具体解释站点沙盒期的原因表现与解决的方法
    工作,究竟意味着什么
    MVC之查询demo
    学习开淘宝网店
    快排的两种写法
    QTableWidget具体解释(样式、右键菜单、表头塌陷、多选等) (非代理)
  • 原文地址:https://www.cnblogs.com/NicolasLiaoran/p/12964100.html
Copyright © 2011-2022 走看看