BegainInvoke 和EndInvoke

1、BegainInvoke 从线程池中获取一个线程,并且让引用方法在新的线程中运行。
2、BegainInvoke 返回给调用线程一个IAsyncResult接口的对象的引用。这个接口引用包含了在线程池中运行的异步方法的当前状态,原始线程然后可以继续运行。
3、EndInvoke 方法用来获取有异步方法调用返回的值。并且释放线程所用的资源。
EndInvoke 有以下的特性。
接受一个由BegainInvoke方法返回的IAsyncResult对象的引用,并找到它关联的线程。
如果线程池里面的线程退出了,会做以下的事情。
清理退出的线程的状态并释放其资源。
找到引用方法的返回值并作为其返回值
如果调用的线程池里面的线程还在运行,调用线程就会停止并等待。直到清理完毕并由返回值。
EndInvoke 是为开启的线程进行清理。所以确保每一个BegainInvoke 都会调用EndInvoke。
如果EndInvoke 出现异常。则会抛出异常。

异步编程模式有三种模式
(1)等待到一直结束

  
 delegate long Mysum(int frist, int second);
    class Program
    {
        static void Main(string[] args)
        {
            Mysum mysum = new Mysum(Sum);
            Console.WriteLine("Before BegainInvoke");
            IAsyncResult iar = mysum.BeginInvoke(3, 5, null, null);//开始异步调用 
            Console.WriteLine("After BegainInvoke");
            Console.WriteLine("Doing Stuff");
            long Result = mysum.EndInvoke(iar);//等待结束并返回结果。
            Console.WriteLine("After EndInvoke:{0}", Result);
            Console.ReadLine();
        }
        static long Sum(int x,int y)
        {
            Console.WriteLine("      inside sum");
            Thread.Sleep(10000);
            return x + y;
        }
    }
 
IAsyncResult 接口被AsyncResult对象包含,AsyncResult类表现为异步的状态。 BegainInvoke 方法调用时时,系统会创建一个AsyncResult 对象。不会返回类对象的引用,而是返回对象中包含IAsyncResult接口的引用。 AsyncResult 对象包含Asyncdelegate属性,它返回一个指向被调用来开启异步方法的委托的引用。这个属性时类的一部分,不是接口的一部分。 IsCompleted 属性返回一个布尔值,表示异步是否完成。 AsyncState属性返回一个对象的引用。作为BegainInvoke方法调用时State的参数。返回是一个Object类型的引用。

2、循环模式
循环模式在判断IAsyncResult中的IsCompleted 是否为True,如果一直为false,则处理循环内的事情,如果TRUE 则返回主线程中去。
代码如下

/// 
        /// 异步委托的循环模式
        /// 
        /// 
        static void Main(string[] args)
        {
            Mysum mysum = new Mysum(Sum);
            Console.WriteLine("Before BegainInvoke");
            IAsyncResult iar = mysum.BeginInvoke(3, 5, null, null);//开始异步调用 
            Console.WriteLine("After BegainInvoke");
            while (!iar.IsCompleted)
            {
                Console.WriteLine("Not Done");
                for (int i = 0; i < 1000000; i++)
                {
                    Console.WriteLine($"{i}");
                    if (iar.IsCompleted)
                    {
                        break;
                    }
                }
            }
            Console.WriteLine("Done");
            long Result = mysum.EndInvoke(iar);//等待结束并返回结果。
            Console.WriteLine("After EndInvoke:{0}", Result);
            Console.ReadLine();
        }
        static long Sum(int x, int y)
        {
            Console.WriteLine("      inside sum");
            Thread.Sleep(100);
            return x + y;
        }

3、回调模式,回调模式不回阻塞线程。而一直等待模式,循环模式,也会存在阻塞线程,而回调模式不存在阻塞线程。BegainInvoke 开始异步线程后,立即返回主线程,结果由回调函数处理。
理论
回调方法的签名和返回参数必须跟AsyncCallback 委托类型所描述的一致。它需要方法接受一个IAsyncResult 作为参数,并且返回参数为Void
案例如下

static void Main(string[] args)
        {
            Mysum summ = new Mysum(Sum);
            Console.WriteLine("Before BegainInvoke");
            IAsyncResult iar = summ.BeginInvoke(5, 2, new AsyncCallback(CallWhenDone), null);
            Console.WriteLine("Doing more work in Main");
            Thread.Sleep(500);
            Console.WriteLine("Doing with Main.Exting");
            Console.ReadLine();
        }
    //回调函数
    static void CallWhenDone(IAsyncResult iar)
    {
        Console.WriteLine("            inside CallWhenDone");

        AsyncResult ar = (AsyncResult)iar;//显示转换为AsyncResult类。
        Mysum sums=(Mysum)ar.AsyncDelegate;//返回一个指向被调用来开启异步方法的委托的引用
        long result = sums.EndInvoke(iar);

        Console.WriteLine("      The result is {0}", result);
    }



    //委托方法
    static long Sum(int x,int y)
    {
        Console.WriteLine("         inside sum");
        Thread.Sleep(100);
        return x + y;
    }

posted @ 2022-02-16 16:17  跨界专家  阅读(151)  评论(0)    收藏  举报