1. 程式人生 > >分享一個非同步執行緒,輪詢的demo

分享一個非同步執行緒,輪詢的demo

//建立一個控制檯應用程式如下:
using System;
using System.Threading;

namespace ConsoleApplication1
{
    public delegate string AsyncDelegate(int callDuration, out int threadId);
    class Program
    {
        static void Main(string[] args)
        {
            //Fun1();
            //Fun2();
            //Fun3();
            Fun4();
            Console.ReadLine();
        }
        private static int threadId;

        //阻塞等待   使用 EndInvoke 等待非同步呼叫  
        static void Fun1()
        {
            //建立示例類的例項。
            AsyncDemo ad = new AsyncDemo();
            // 建立委託
            AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);
            // 委託在這裡開始非同步呼叫。
            IAsyncResult ar = dlgt.BeginInvoke(5000,out threadId, null, null);
            //人為的執行緒阻塞。
            Thread.Sleep(0);
            //Thread.CurrentThread.Name = "主執行緒";
            Console.WriteLine("主執行緒 {0}開始工作",Thread.CurrentThread.ManagedThreadId);
            // 委託開始EndInvoke呼叫,這個過程會使主執行緒等待非同步呼叫完成並返回結果。
            string ret = dlgt.EndInvoke(out threadId, ar);
            Console.WriteLine("使用 EndInvoke 等待非同步呼叫!!!");
            Console.WriteLine("非同步執行緒 {0},返回值 \"{1}\".", threadId, ret);
            Console.WriteLine("主執行緒{0}結束工作", Thread.CurrentThread.ManagedThreadId);
        }
        
        //阻塞等待  使用 WaitHandle 等待非同步呼叫
        static void Fun2()
        {
            AsyncDemo ad = new AsyncDemo();
            AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);
            IAsyncResult ar = dlgt.BeginInvoke(5000,out threadId, null, null);
            Thread.Sleep(0);
            Console.WriteLine("主執行緒 {0}開始工作", Thread.CurrentThread.ManagedThreadId);
            //主執行緒在這裡等待,直到非同步執行緒執行完。
            ar.AsyncWaitHandle.WaitOne();
            // 和前一方案的區別在於,你可以在非同步呼叫完成後,獲取非同步呼叫返回值之前
            //在這裡做點任何你想作的事。
            //呼叫EndInvoke獲取非同步呼叫的返回結果.
            string ret = dlgt.EndInvoke(out threadId, ar);
            Console.WriteLine("使用 WaitHandle 等待非同步呼叫!!!");
            Console.WriteLine("非同步執行緒 {0},返回值 \"{1}\".", threadId, ret);
            Console.WriteLine("主執行緒{0}結束工作", Thread.CurrentThread.ManagedThreadId);
        }

        //輪詢狀態    輪詢非同步呼叫完成
        static void Fun3()
        {
            AsyncDemo ad = new AsyncDemo();
            AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);
            IAsyncResult ar = dlgt.BeginInvoke(5000,out threadId, null, null);
            Console.WriteLine("使用輪詢非同步呼叫!!!");
            Console.WriteLine("主執行緒 {0}開始工作", Thread.CurrentThread.ManagedThreadId);
            //這裡每隔10毫秒就檢測(輪詢)一下非同步執行的狀態,
            //直到非同步呼叫完成,IsCompleted的值變為ture為止。
            int count = 0;
            DateTime a = DateTime.Now;
            while (ar.IsCompleted == false)
            {
                Thread.Sleep(10);
                count++;
            }
            string dt = (DateTime.Now - a).ToString();
            Console.WriteLine(count);
            Console.WriteLine("程式耗時"+dt);
            //還記得微軟的那個善意的提醒嗎?雖然IsCompleted為true了,
            //我們還是呼叫一下EndInvoke,來獲取返回值。
            string ret = dlgt.EndInvoke(out threadId, ar);
            Console.WriteLine("非同步執行緒 {0},返回值 \"{1}\".", threadId, ret);
            Console.WriteLine("主執行緒{0}結束工作", Thread.CurrentThread.ManagedThreadId);
        }

        //通知機制    非同步呼叫完成時執行回撥方法
        static void Fun4()
        {
            AsyncDemo ad = new AsyncDemo();
            AsyncDelegate dlgt = new AsyncDelegate(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();
        }
        //回撥函式必須嚴格的遵照AsyncCallback委託的簽名。
        static void CallbackMethod(IAsyncResult ar)
        {
            //在這裡,上面那個dlgt作為引數的作用得到了體現,原來它就是為了完成對EndInvoke的呼叫啊。
            AsyncDelegate dlgt = (AsyncDelegate)ar.AsyncState;
            //通過對EndInvoke的呼叫獲取返回值。
            string ret = dlgt.EndInvoke(out threadId, ar);
            Console.WriteLine("非同步執行緒 {0},返回值 \"{1}\".", threadId, ret);
        }
    }
    //使用非同步程式設計模型 
    public class AsyncDemo
    {
        public string TestMethod(int callDuration, out int threadId)
        {
            Console.WriteLine("非同步方法開始工作");
            Thread.Sleep(callDuration);
            //Thread.CurrentThread.Name = "非同步執行緒";
            threadId = Thread.CurrentThread.ManagedThreadId; 
            return "非同步方法執行時間 " + callDuration.ToString();
        }
    }

}

上面的註釋都很詳細相信大家很容易看得懂。

為博主轉載,忘記此demo的出處了,如若侵權,即可刪除。