首页 > 代码库 > 常见异步机制分析

常见异步机制分析

本章内容:

  1、使用 EndInvoke 等待异步调用

  2、使用 WaitHandle 等待异步调用

  3、轮询状态    轮询异步调用完成

  4、通知机制    异步调用完成时执行回调方法

  异步操作通常用于执行完成时间可能较长的任务,避免阻塞,这是与线程有所相似的地方,具体异同自行百度吧,推荐《多线程与异步的区别》这篇文章,讲得很好。

  

创建我们使用到的模型和委托

public delegate string AsyncDele(int callDuration, out int threadId);//使用异步编程模型     public class AsyncDemoModel    {        public string TestMethod(int callDuration, out int threadId)        {            Console.WriteLine("异步方法开始工作");            Thread.Sleep(callDuration);            threadId = Thread.CurrentThread.ManagedThreadId;             return "异步方法执行时间 " + callDuration.ToString();        }    }

1、使用 EndInvoke 等待异步调用

   static void Func1()        {            AsyncDemoModel ad = new AsyncDemoModel();            // 创建委托            AsyncDele dlgt = new AsyncDele(ad.TestMethod);            // 委托在这里开始异步调用。            IAsyncResult ar = dlgt.BeginInvoke(5000,out threadId, null, null);            //人为的线程阻塞。            Thread.Sleep(1000);            Console.WriteLine("主线程 {0}开始工作",Thread.CurrentThread.ManagedThreadId);            // 委托开始EndInvoke调用,这个过程会使主线程等待异步调用完成并返回结果。            Console.WriteLine("使用 EndInvoke 等待异步调用!!!");            string ret = dlgt.EndInvoke(out threadId, ar);            Console.WriteLine("异步线程 {0},返回值 \"{1}\".", threadId, ret);            Console.WriteLine("主线程{0}结束工作", Thread.CurrentThread.ManagedThreadId);        }

2、使用 WaitHandle 等待异步调用

 static void Func2()        {            AsyncDemoModel ad = new AsyncDemoModel();            AsyncDele dlgt = new AsyncDele(ad.TestMethod);            IAsyncResult ar = dlgt.BeginInvoke(5000,out threadId, null, null);            Thread.Sleep(0);            Console.WriteLine("主线程 {0}开始工作", Thread.CurrentThread.ManagedThreadId);            //主线程在这里等待,直到异步线程执行完。            Console.WriteLine("使用 WaitHandle 等待异步调用!!!");            ar.AsyncWaitHandle.WaitOne();            // 和前一方案的区别在于,你可以在异步调用完成后,获取异步调用返回值之前            Console.WriteLine("和前一方案的区别在于,你可以在异步调用完成后,获取异步调用返回值之前");            //在这里做点任何你想作的事。            //调用EndInvoke获取异步调用的返回结果.            string ret = dlgt.EndInvoke(out threadId, ar);            Console.WriteLine("异步线程 {0},返回值 \"{1}\".", threadId, ret);            Console.WriteLine("主线程{0}结束工作", Thread.CurrentThread.ManagedThreadId);        }

3、轮询

   static void Func3()        {            AsyncDemoModel ad = new AsyncDemoModel();            AsyncDele dlgt = new AsyncDele(ad.TestMethod);            IAsyncResult ar = dlgt.BeginInvoke(5000,out threadId, null, null);            Console.WriteLine("使用轮询异步调用!!!");            Console.WriteLine("主线程 {0}开始工作", Thread.CurrentThread.ManagedThreadId);            //这里每隔10毫秒就检测(轮询)一下异步执行的状态,            //直到异步调用完成,IsCompleted的值变为ture为止。            while (ar.IsCompleted == false)            {                Thread.Sleep(10);            }            //还是调用一下EndInvoke,来获取返回值。            string ret = dlgt.EndInvoke(out threadId, ar);            Console.WriteLine("异步线程 {0},返回值 \"{1}\".", threadId, ret);            Console.WriteLine("主线程{0}结束工作", Thread.CurrentThread.ManagedThreadId);        }

4、通知机制

 static void Func4()        {            AsyncDemoModel ad = new AsyncDemoModel();            AsyncDele dlgt = new AsyncDele(ad.TestMethod);            //注意第三个参数,这就是我们要用到的回调方法。            //第四个参数可以是任何Object对象,这里它就是            //执行异步调用的委托本身,把委托本身传递进去的原因在下面可以看到。            Console.WriteLine("异步调用完成时执行回调!!!");            Console.WriteLine("主线程 {0}开始工作", Thread.CurrentThread.ManagedThreadId);            IAsyncResult ar = dlgt.BeginInvoke(5000,out threadId, new AsyncCallback(CallbackMethod), dlgt);            Console.WriteLine("主线程 {0}结束工作", Thread.CurrentThread.ManagedThreadId);            Console.ReadLine();        }        //回调函数        static void CallbackMethod(IAsyncResult ar)        {            //在这里,上面那个dlgt作为参数的作用得到了体现,原来它就是为了完成对EndInvoke的调用。            AsyncDele dlgt = (AsyncDele)ar.AsyncState;            //通过对EndInvoke的调用获取返回值。            string ret = dlgt.EndInvoke(out threadId, ar);            Console.WriteLine("异步线程 {0},返回值 \"{1}\".", threadId, ret);        }

 

常见异步机制分析