1. 程式人生 > >C# 多執行緒 用委託實現非同步_呼叫委託的BeginInvoke和EndInvoke方法

C# 多執行緒 用委託實現非同步_呼叫委託的BeginInvoke和EndInvoke方法

1.C#中的每一個委託都內建了BeginInvoke和EndInvoke方法,如果委託的方法列表裡只有一個方法,那麼這個方法就可以非同步執行(不在當前執行緒裡執行,另開闢一個執行緒執行)。委託的BeginInvoke和EndInvoke方法就是為了上述目的而生的。

2.原始執行緒發起了一個非同步執行緒,有如下三種執行方式:

方式一:等待一直到完成,即原始執行緒在發起了非同步執行緒以及做了一些必要處理之後,原始執行緒就中斷並等待非同步執行緒結束再繼續執行。

方式二:輪詢,即原始執行緒定期檢查發起的執行緒是否完成,如果沒有則可以繼續做一些其它事情。

方式三:回撥,即原始執行緒一直執行,無需等待或檢查發起的執行緒是否完成。在發起的執行緒執行結束,發起的執行緒就會呼叫使用者定義好的回撥方法,由這個回撥方法在呼叫EndInvoke之前處理非同步方法執行得到的結果。

3.一個控制檯小程式,使用了上面三種方式,執行結果如下:


4.程式碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading;

namespace 用委託實現非同步_呼叫BeginInvoke和EndInvoke方法
{

    delegate long MyDel(int first,int second); //宣告委託型別

    class Program
    {
        //宣告委託型別的方法
        static long Sum(int x,int y) 
        {
            Console.WriteLine("                    Inside Sum");
            Thread.Sleep(200);
            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 WaitUntilDoneStyle()
        {
            MyDel del = new MyDel(Sum);
            Console.WriteLine("Before BeginInvoke");
            IAsyncResult iar = del.BeginInvoke(3, 5, null, null); //開始非同步呼叫
            Console.WriteLine("After BeginInvoke");

            Console.WriteLine("Doing main stuff before");
            long result = del.EndInvoke(iar); //等待非同步執行緒結束並獲取結果
            Console.WriteLine("After EndInvoke:{0}", result);
            Console.WriteLine("Doing main stuff after");
        }

        //方式二:輪詢檢查非同步執行緒是否結束,若沒結束則執行主執行緒
        static void LunXunPollingStyle()
        {
            MyDel del = new MyDel(Sum);
            Console.WriteLine("Before BeginInvoke");
            IAsyncResult iar = del.BeginInvoke(3, 5, null, null); //開始非同步呼叫
            Console.WriteLine("After BeginInvoke");

            while (!iar.IsCompleted)
            {
                Console.WriteLine("Not Done.Doing main stuff");
                //繼續處理主執行緒事情
                for (long i = 0; i < 10000000; i++)
                    ;
            }
            Console.WriteLine("Done");
            long result = del.EndInvoke(iar); //呼叫EndInvoke來獲取結果並進行清理
            Console.WriteLine("Result: {0}", result);
        }

        //方式三:回撥方式,當非同步執行緒結束,系統呼叫使用者自定義的方法來處理結果(包括呼叫委託的EndInvoke方法)
        static void CallBackStyle()
        {
            MyDel del = new MyDel(Sum);
            Console.WriteLine("Before BeginInvoke");
            IAsyncResult iar = del.BeginInvoke(3, 5, new AsyncCallback(CallWhenDone), null);
            Console.WriteLine("After BeginInvoke");
            Console.WriteLine("Doing more work in main.");
            Thread.Sleep(500);
            Console.WriteLine("Done with Main. Exiting.");
        }

        static void Main(string[] args)
        {
            //方式一:等待非同步執行緒結束,再繼續執行主執行緒
            Console.WriteLine();
            Console.WriteLine("--------方式一:等待非同步執行緒結束,再繼續執行主執行緒--------");
            WaitUntilDoneStyle();

            //方式二:輪詢檢查非同步執行緒是否結束,若沒結束則執行主執行緒
            Console.WriteLine();
            Console.WriteLine("--------方式二:輪詢檢查非同步執行緒是否結束,若沒結束則執行主執行緒--------");
            LunXunPollingStyle();

            //方式三:回撥方式,當非同步執行緒結束,系統呼叫使用者自定義的方法來處理結果(包括呼叫委託的EndInvoke方法)
            Console.WriteLine();
            Console.WriteLine("--------方式三:回撥方式,當非同步執行緒結束,系統呼叫使用者自定義的方法來處理結果(包括呼叫委託的EndInvoke方法)--------");
            CallBackStyle();
        }

       
    }
}