C#中的非同步呼叫及非同步設計模式(一)

來源:互聯網
上載者:User

 

近期項目中使用了不少非同步作業,關於“非同步”做個總結。總結的內容大部分都來自於MSDN,還有一些自己的心得。

關於“非同步”的使用可分為:使用層面和類庫設計層面,細分如下:

一、使用非同步方式調用同步方法(使用層面)。

二、使用 IAsyncResult 調用非同步方法呼叫(使用層面)。

三、基於 IAsyncResult 的非同步設計模式(設計層面)。

四、事件架構非同步模式(設計層面)。

關於上述非同步編程的幾個方面,下面分別做以詳述。

一、使用非同步方式調用同步方法(使用層面)

.NET Framework 允許您非同步呼叫任何方法。為此,應定義與您要調用的方法具有相同簽名的委託;公用語言運行庫會自動使用適當的簽名為該委託定義 BeginInvoke 和 EndInvoke 方法。BeginInvoke 方法可啟動非同步呼叫,EndInvoke 方法檢索非同步呼叫的結果。調用 BeginInvoke 後可隨時調用 EndInvoke 方法;如果非同步呼叫尚未完成,EndInvoke 將一直阻止調用線程,直到非同步呼叫完成後才允許調用線程執行。

該調用方式是使用委託進行非同步呼叫,其實質是:調用“BeginInvoke”方法,公用語言運行庫 (CLR) 將對請求進行排隊並立即返回到調用方。將對來自線程池的線程調用該目標方法。提交請求的原始線程自由地繼續與目標方法並存執行,該目標方法是線上程池線程啟動並執行。

在非同步呼叫啟動後,在等待非同步呼叫結果的時候,可以進行以下四種方法。

·                     進行某些操作,然後調用 EndInvoke 一直阻止到調用完成。

using System;using System.Threading;namespace Examples.AdvancedProgramming.AsynchronousOperations{    public class AsyncMain    {        public static void Main()        {            // The asynchronous method puts the thread id here.            int threadId;            // Create an instance of the test class.            AsyncDemo ad = new AsyncDemo();            // Create the delegate.            AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);            // Initiate the asychronous call.            IAsyncResult result = caller.BeginInvoke(3000,                out threadId, null, null);            Thread.Sleep(0);            Console.WriteLine("Main thread {0} does some work.",                Thread.CurrentThread.ManagedThreadId);            // 調用此方法將會一直等待非同步作業完成,並阻塞當前線程。            string returnValue = caller.EndInvoke(out threadId, result);            Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".",                threadId, returnValue);        }    }}

 

·                     進行某些操作,然後使用 IAsyncResult..::.AsyncWaitHandle 屬性擷取 WaitHandle,使用它的 WaitOne 方法(該方法可以設定一個逾時時間)一直阻止執行直到發出 WaitHandle 訊號,然後調用 EndInvoke。

using System;using System.Threading;namespace Examples.AdvancedProgramming.AsynchronousOperations{    public class AsyncMain    {        static void Main()        {            // The asynchronous method puts the thread id here.            int threadId;            // Create an instance of the test class.            AsyncDemo ad = new AsyncDemo();            // Create the delegate.            AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);            // Initiate the asychronous call.            IAsyncResult result = caller.BeginInvoke(3000,                out threadId, null, null);            Thread.Sleep(0);            Console.WriteLine("Main thread {0} does some work.",                Thread.CurrentThread.ManagedThreadId);            // 調用此方法將會一直等待非同步作業完成,並阻塞當前線程。            result.AsyncWaitHandle.WaitOne();            // Perform additional processing here.            // Call EndInvoke to retrieve the results.            string returnValue = caller.EndInvoke(out threadId, result);            Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".",                threadId, returnValue);        }    }}

 

·                     進行某些操作,然後輪詢由 BeginInvoke 返回的 IAsyncResult,確定非同步呼叫何時完成,然後調用 EndInvoke。

using System;using System.Threading;namespace Examples.AdvancedProgramming.AsynchronousOperations{    public class AsyncMain    {        static void Main()        {            // The asynchronous method puts the thread id here.            int threadId;            // Create an instance of the test class.            AsyncDemo ad = new AsyncDemo();            // Create the delegate.            AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);            // Initiate the asychronous call.            IAsyncResult result = caller.BeginInvoke(3000,                out threadId, null, null);            // 等待結果返回            while (result.IsCompleted == false)            {                Thread.Sleep(10);            }            // Call EndInvoke to retrieve the results.            string returnValue = caller.EndInvoke(out threadId, result);            Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".",                threadId, returnValue);        }    }}

 

·                     將用於回調方法的委託傳遞給 BeginInvoke。非同步呼叫完成後,將在 ThreadPool 線程上執行該方法。該回調方法將調用 EndInvoke。注意:該回呼函數的執行是在另外一個線程上。

 

using System;using System.Threading;namespace Examples.AdvancedProgramming.AsynchronousOperations{    public class AsyncMain     {        // Asynchronous method puts the thread id here.        private static int threadId;        static void Main() {            // Create an instance of the test class.            AsyncDemo ad = new AsyncDemo();            // Create the delegate.            AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);            // Initiate the asychronous call.  Include an AsyncCallback            // delegate representing the callback method, and the data            // needed to call EndInvoke.            IAsyncResult result = caller.BeginInvoke(3000,                out threadId,                 new AsyncCallback(CallbackMethod),                caller );            Console.WriteLine("Press Enter to close application.");            Console.ReadLine();        }        // Callback method must have the same signature as the        // AsyncCallback delegate.        static void CallbackMethod(IAsyncResult ar)         {            // Retrieve the delegate.            AsyncMethodCaller caller = (AsyncMethodCaller) ar.AsyncState;            // Call EndInvoke to retrieve the results.            string returnValue = caller.EndInvoke(out threadId, ar);            Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".",                threadId, returnValue);        }    }}

二、使用 IAsyncResult 調用非同步方法呼叫(使用層面)

.NET Framework 的許多方面都支援非同步編程功能,這些方麵包括:

·                     檔案 IO、流 IO、通訊端 IO。

·                     網路。

·                     遠端通道(HTTP、TCP)和代理。

·                     使用 ASP.NET 建立的 XML Web services。

·                     ASP.NET Web Form。

·                     使用 MessageQueue 類的訊息佇列。

這些已經實現了非同步作業的類或組件,可以直接調用其非同步方法呼叫(以Begin和End開頭)。調用非同步方法呼叫後等待結果可以參考“非同步呼叫同步方法”的處理。

 

三、基於 IAsyncResult 的非同步設計模式(設計層面)

待續...

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.