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