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

  • 相关阅读:
    使用python向Redis批量导入数据
    SkinSharp用法
    java设计模式演示样例
    [LeetCode] Search for a Range [34]
    Java 实现组合(Composite)模式
    机房收费系统重构中的一些感受
    qt学习笔记(五) QGraphicsPixmapItem与QGraphicsScene的编程实例 图标拖动渐变效果
    Windows下FFmpeg高速入门
    C# DataTable的詳細使用方法
    NGUI 3.5教程(六)Font字体
  • 原文地址:https://www.cnblogs.com/NicolasLiaoran/p/12964100.html
Copyright © 2011-2022 走看看