C# - 多線程之 非同步編程

來源:互聯網
上載者:User

標籤:響應   事務   c#   string   ack   console   處理   輪詢   操作   

非同步編程
  • 同步編程,請求響應模型,同步化、順序化、事務化。
  • 非同步編程,事件驅動模型,以 Fire and Forget 方式實現。

非同步編程模式

?-§-?非同步編程模型 (APM) 模式: IAsyncResult 模式,非同步作業需要 Begin 和 End 方法;
?-§-?事件架構非同步模式(EAP):事件、事件處理常式委託類型和 EventArg 衍生類別型;
?-§-?基於任務的非同步模式(TAP):推薦模式,.NET Framework 4 引入,基於 System.Threading.Tasks 命名空間,利用一種方法表示非同步作業的啟動和完成;

?類 LogicalMethodInfo 提供 Invoke 和 BeginInvoke 方法支援同步或非同步執行委託的方法:

 public sealed class System.Web.Services.Protocols.LogicalMethodInfo{     public object[] Invoke(object target, object[] values);     public IAsyncResult BeginInvoke(object target, object[] values, AsyncCallback callback, object asyncState);     public object[] EndInvoke(object target, IAsyncResult asyncResult); }

?其中,target 是委託方法所屬的類執行個體,values 是委託方法的參數列表。

非同步方法呼叫調用模式

?三種方法調用模式區別:原線程擷取非同步線程已經完成的訊息的方式。
?
? 其中,BeginInvoke 方法用於啟動非同步呼叫,EndInvoke 方法用於檢索並擷取非同步呼叫結果然後釋放線程佔用的資源。BeginInvoke 立即返回,不等待非同步方法呼叫調用完成,同時在調用時建立一個 AsyncResult 類對象,但是 BeginInvoke 返回 IAsyncResult 介面的引用,可用於監視非同步方法呼叫的調用進度,調用 BeginInvoke 後可隨時調用 EndInvoke 方法。
?
? 其中,IAsyncResult 介面 的 AsyncState 屬性擷取 Object 類型的對象可以作為 BeginInvoke 方法調用時的 State 參數(可根據需要自訂)。 委託定義和非同步委託方法定義為:

 public delegate int MyDel(string str); public static int DelFun(string str){    Console.WriteLine("非同步線程執行方法:DelFun() in " + Thread.CurrentThread.ManagedThreadId);    Thread.Sleep(3000);    return str.Length; }

:BeginInvoke 的參數是在編譯時間根據委託的定義動態產生的,前面參數的個數和類型與委託定義中的參數個數和類型相同,後兩個參數分別是 AsyncCallback 和 Object 類型。BeginInvoke 的調用者的方法列表有且只能有一個方法。BeginInvoke 第三個參數可為任意類型,最終都可通過 AsyncState 屬性獲得對應值。

等待模式 Waiting-Until-Done  

如果非同步方法呼叫調用未完成,EndInvoke 將一直阻塞到非同步方法呼叫調用完成才執行。其中,等待 WaitHandle 是一項常用的線程同步技術,可以通過 BeginInvoke 返回的 IAsyncResult 的 AsyncWaitHandle 屬性調用 WaitOne() 方法阻止當前線程,直到擷取到非同步方法呼叫調用完成時發出的 WaitHandle 訊號。

 public static void AsyncWaitingTest() {             MyDel myDel = new MyDel(TestClass.DelFun);     Console.WriteLine("主線程:AsyncWaitingTest() in " + Thread.CurrentThread.ManagedThreadId);    IAsyncResult iar = myDel.BeginInvoke("sqh", null, null);    Console.WriteLine("主線程繼續執行... in " + Thread.CurrentThread.ManagedThreadId);     while (!iar.AsyncWaitHandle.WaitOne(1000)){       Console.WriteLine("Waiting... AsyncMethod()");    }    int strLen = myDel.EndInvoke(iar);    Console.WriteLine("Str Length:{0}", strLen); }

輪詢模式 Polling  

利用 BeginInvoke 返回的 IAsyncResult 的 IsCompleted 屬性來判斷非同步方法呼叫調用是否完成。

 public static void AsyncPollingTest() {    MyDel myDel = new MyDel(TestClass.DelFun);     Console.WriteLine("主線程:AsyncPollingTest() in " + Thread.CurrentThread.ManagedThreadId);    IAsyncResult iar = myDel.BeginInvoke("sqh", null, null);    Console.WriteLine("主線程繼續執行... in " + Thread.CurrentThread.ManagedThreadId);     while (!iar.IsCompleted){       Thread.Sleep(1000);       Console.WriteLine("Waiting... AsyncMethod()");    }    int strLen = myDel.EndInvoke(iar);    Console.WriteLine("Str Length:{0}", strLen); }

回調模式 Callback  

調用 BeginInvoke 時提供回調方法,非同步方法呼叫調用結束後,回調方法在 ThreadPool 中的非同步線程上自動執行,並調用 EndInvoke 方法。
  回調方法形如:void AsyncCallback(IAsyncResult iar);

 public static void AsyncCallbackTest() {    MyDel myDel = new MyDel(TestClass.DelFun);     Console.WriteLine("主線程:AsyncCallbackTest() in " + Thread.CurrentThread.ManagedThreadId);    IAsyncResult iar = myDel.BeginInvoke("sqh", CallbackMethod, myDel);    Console.WriteLine("主線程繼續執行... in " + Thread.CurrentThread.ManagedThreadId);    // ... 其他動作,獨立於非同步線程 } public static void CallbackMethod(IAsyncResult iar) {    Console.WriteLine("非同步方法呼叫執行完畢,開始執行回調方法 in " + Thread.CurrentThread.ManagedThreadId);     //AsyncResult ar = (AsyncResult)iar;  // **推薦**    //MyDel myDel = (MyDel)ar.AsyncDelegate;               MyDel myDel = (MyDel)iar.AsyncState;  // 這種調用方式 BeginInvoke 需要 myDel 參數     int result = myDel.EndInvoke(iar);    Console.WriteLine(result); }

其他:當委託的方法列表中有多個方法時,可以利用 GetInvocationList() 方法得到 Delegate[] 數組,然後依次調用 BeginInvoke 方法,不同的方法線上程池的不同線程上運行!
 
參考
[1]. 非同步編程模式系列(1-6);
[2]. 非同步方法呼叫調用模式總結; 非同步呼叫四種方法;

C# - 多線程之 非同步編程

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.