C#實現異步的常用方式總結
c#實現異步的常用方式總結
前言
微信群里的一個提問引發的這個問題,c#異步有多少種實現方式?首先想要知道c#異步有多少中實現方式,首先我們要知道.net提供的執行異步操作的三種模式,然后再去了解c#異步實現的方式。
.net異步編程模式
.net 提供了執行異步操作的三種模式:
- 基于任務的異步模式 (tap),該模式使用單一方法表示異步操作的開始和完成。 tap 是在 .net framework 4 中引入的。這是在 .net 中進行異步編程的推薦方法。c# 中的async和await關鍵詞以及 visual basic 中的async和await運算符為 tap 添加了語言支持。 有關詳細信息,請參閱基于任務的異步模式 (tap)。
- 基于事件的異步模式 (eap),是提供異步行為的基于事件的舊模型。 這種模式需要后綴為async的方法,以及一個或多個事件、事件處理程序委托類型和eventarg派生類型。 eap 是在 .net framework 2.0 中引入的。 建議新開發中不再使用這種模式。 有關詳細信息,請參閱基于事件的異步模式 (eap)。
- 異步編程模型 (apm) 模式(也稱為iasyncresult模式),這是使用iasyncresult接口提供異步行為的舊模型。 在這種模式下,同步操作需要begin和end方法(例如,beginwrite和endwrite以實現異步寫入操作)。 不建議新的開發使用此模式。 有關詳細信息,請參閱異步編程模型 (apm)。
c#異步有四種實現方式
c# 異步有多種實現方式,可歸納為以下幾類:
1、異步方法(async methodtap模式)
使用async/await關鍵字實現異步編程,這是比較常用的一種異步實現方式。例如:
public async task testdosomeasync() { await task.delay(1000); console.writeline("async method completed."); }
2、任務并行庫(tpl, task parallel librarytap模式)
通過 task 和 task<t> 類型實現異步編程,可以利用多核處理器,并發執行多個獨立的任務。例如:
public static async void main(string[] args) { await task.run(() => { console.writeline("test task 1 completed."); }); await task.run(() => { console.writeline("test task 2 completed."); }); // 等待所有任務完成 task.waitall(); }
3、asynchronous programming model(apm模式)
是一種經典的異步編程模式,需要手動創建回調函數,用于處理完成或錯誤的通知。可以通過 iasyncresult 設計模式的 begin 和 end 方法來實現,其中 begin 方法開始異步操作,而 end 方法在異步操作完成時執行,并返回異步操作的結果。
需要注意的是,apm 模式通過 iasyncresult 接口來存儲異步操作的狀態和結果,相對比較復雜,代碼量也較大。同時,在使用 apm 模式時,還需要手動處理回調函數和等待異步操作完成等細節工作,使得開發起來相對較為繁瑣。
class program { static void main(string[] args) { // 創建異步操作類實例 myasyncclass asyncclass = new myasyncclass(); // 開始異步操作 iasyncresult result = asyncclass.begindowork(null, null); // 主線程執行其他操作 // 等待異步操作完成并獲取結果 int res = asyncclass.enddowork(result); // 處理異步操作的結果 console.writeline("result: " + res); console.readline(); } } class myasyncclass { /// <summary> /// 異步執行的方法 /// </summary> /// <param name="callback">callback</param> /// <param name="state">state</param> /// <returns></returns> public iasyncresult begindowork(asynccallback callback, object state) { // 創建一個新的異步操作對象 myasyncresult result = new myasyncresult(state); // 開始異步操作 thread thread = new thread(() => { try { // 執行一些操作 int res = 1 + 2; // 設置異步操作的結果 result.result = res; // 觸發回調函數 callback?.invoke(result); } catch (exception ex) { // 設置異步操作的異常 result.error = ex; // 觸發回調函數 callback?.invoke(result); } }); thread.start(); // 返回異步操作對象 return result; } /// <summary> /// 結束異步執行的方法 /// </summary> /// <param name="result">result</param> /// <returns></returns> public int enddowork(iasyncresult result) { // 將 iasyncresult 轉換為 myasyncresult 類型,并等待異步操作完成 myasyncresult myresult = (myasyncresult)result; myresult.asyncwaithandle.waitone(); // 在異步操作中拋出異常 if (myresult.error != null) { throw myresult.error; } // 返回異步操作的結果 return myresult.result; } } class myasyncresult : iasyncresult { public bool iscompleted => asyncwaithandle.waitone(0); public waithandle asyncwaithandle { get; } = new manualresetevent(false); public object asyncstate { get; } public bool completedsynchronously => false; public int result { get; set; } /// <summary> /// 存儲異步操作的結果或異常信息 /// </summary> public exception error { get; set; } /// <summary> /// 構造函數 /// </summary> /// <param name="asyncstate">asyncstate</param> public myasyncresult(object asyncstate) { asyncstate = asyncstate; } }
4、event-based asynchronous pattern(eap模式)
一種已過時的異步編程模式,需要使用事件來實現異步編程。例如:
需要注意的是,eap 模式通過事件來實現異步編程,相對于 apm 模式更加簡潔易懂,同時也避免了手動處理回調函數等細節工作。但是,eap 模式并不支持 async/await 異步關鍵字,因此在一些特定的場景下可能不夠靈活。
public class myasyncclass : component { /// <summary> /// 聲明一個委托類型,用于定義異步操作的方法簽名 /// </summary> /// <param name="arg"></param> /// <returns></returns> public delegate int myasyncdelegate(int arg); /// <summary> /// 聲明一個事件,用于通知異步操作的完成 /// </summary> public event myasyncdelegate operationnamecompleted; /// <summary> /// 異步執行方法,接受一個參數 arg /// </summary> /// <param name="arg"></param> public void doworkasync(int arg) { // 將異步操作放入線程池中執行 threadpool.queueuserworkitem(new waitcallback(dowork), arg); } /// <summary> /// 真正的異步操作 /// </summary> /// <param name="obj"></param> private void dowork(object obj) { int arg = (int)obj; int res = arg + 1; // 觸發事件,傳遞異步操作的結果 operationnamecompleted?.invoke(res); } }
以上就是c#實現異步的常用方式總結的詳細內容,更多關于c#異步的資料請關注碩編程其它相關文章!