.Net通過(guò)TaskFactory.FromAsync簡(jiǎn)化APM
異步執(zhí)行 I/O 密集型操作是生產(chǎn)高響應(yīng)和可伸縮應(yīng)用程序及組件的關(guān)鍵??勺屇褂脴O少量的線程來(lái)執(zhí)行大量的工作,而無(wú)需阻止任何線程。然而異步編程卻有些麻煩,許多程序員不愿意去做它。
網(wǎng)上有不少通過(guò)lambda 表達(dá)式和AsyncEnumerator 等來(lái)實(shí)現(xiàn)簡(jiǎn)化異步編程的方法,這些方法也確實(shí)行之有效,但在.net 4.0中,我們又多了一種選擇——通過(guò)TaskFactory.FromAsync簡(jiǎn)化APM。
TaskFactory.FromAsync這個(gè)方法非常簡(jiǎn)單,通過(guò)它可以把一個(gè)異步的任務(wù)轉(zhuǎn)換為一個(gè)Task,首先我們來(lái)看一個(gè)簡(jiǎn)單的例子吧:
static IEnumerable<Task> CopyStreamAsync(Stream input, Stream output) { var buffer = new byte[0x2000]; while (true) { var readTask = Task<int>.Factory.FromAsync(input.BeginRead, input.EndRead, buffer, 0, buffer.Length, null); yield return readTask; if (readTask.Result == 0) break; yield return Task.Factory.FromAsync(output.BeginWrite, output.EndWrite, buffer, 0, buffer.Length, null); } }
這個(gè)例子通過(guò)TaskFactory.FromAsync把一系列異步操作轉(zhuǎn)換為了一個(gè)任務(wù)列。雖然這些都是異步操作,但在函數(shù)中卻和同步操作一樣直觀,十分簡(jiǎn)單而清晰。
轉(zhuǎn)換為了的任務(wù)列后,我們就需要來(lái)執(zhí)行這一系列任務(wù),最簡(jiǎn)單的方法如下:
foreach (var task in CopyStreamAsync(input, output)) { task.Wait(); }
這種方式雖然直接有效,但它卻是一種阻塞式的操作,沒有達(dá)到異步的目的,我們一般可以通過(guò)如下方式把這個(gè)任務(wù)列轉(zhuǎn)換為一個(gè)任務(wù),從而實(shí)現(xiàn)異步執(zhí)行。
public static Task Iterate(this TaskFactory factory, IEnumerable<Task> asyncIterator) { var scheduler = factory.Scheduler ?? TaskScheduler.Current; // Get an enumerator from the enumerable var enumerator = asyncIterator.GetEnumerator(); if (enumerator == null) throw new InvalidOperationException(); // Create the task to be returned to the caller. And ensure // that when everything is done, the enumerator is cleaned up. var trs = new TaskCompletionSource<object>(factory.CreationOptions); trs.Task.ContinueWith(_ => enumerator.Dispose(), scheduler); // This will be called every time more work can be done. Action<Task> recursiveBody = null; recursiveBody = antecedent => { try { // If the previous task completed with any exceptions, bail if (antecedent != null && antecedent.IsFaulted) trs.TrySetException(antecedent.Exception); else if (trs.Task.IsCanceled) trs.TrySetCanceled(); else if (enumerator.MoveNext()) enumerator.Current.ContinueWith(recursiveBody, scheduler); // Otherwise, we're done! else trs.TrySetResult(null); } // If MoveNext throws an exception, propagate that to the user catch (Exception exc) { trs.TrySetException(exc); } }; // Get things started by launching the first task factory.StartNew(_ => recursiveBody(null), scheduler); // Return the representative task to the user return trs.Task; }
這個(gè)函數(shù)我是摘錄自ParallelProgrammingSamples中的,里面還有好幾種其它的調(diào)用形式,可以根據(jù)需要選擇合適的方法。
到此這篇關(guān)于.Net通過(guò)TaskFactory.FromAsync簡(jiǎn)化APM的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
總結(jié)Visual Studio下ASP.NET模板化控件中的數(shù)據(jù)綁定
.NET框架中提供了很多數(shù)據(jù)綁定的組件,這里我們就來(lái)總結(jié)Visual Studio下ASP.NET模板化控件中的數(shù)據(jù)綁定,需要的朋友可以參考下2016-06-06IIS服務(wù)器發(fā)布ASP.NET項(xiàng)目
如何在云服務(wù)器上部署一個(gè)項(xiàng)目,需要做哪些配置準(zhǔn)備,本文就來(lái)介紹一下IIS服務(wù)器發(fā)布ASP.NET項(xiàng)目,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03ASP.NET JSON字符串與實(shí)體類的互轉(zhuǎn)換示例代碼
本篇文章主要是對(duì)ASP.NET JSON字符串與實(shí)體類的互轉(zhuǎn)換的示例代碼進(jìn)行了介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2014-01-01repeater、gridview 在綁定時(shí)判斷判斷顯示不同的行樣式或文本
repeater、gridview 在綁定時(shí)判斷判斷顯示不同的行樣式或文本的實(shí)現(xiàn)代碼,需要的朋友可以參考下。2011-09-09asp.net 計(jì)劃任務(wù)管理程序?qū)崿F(xiàn),多線程任務(wù)加載
b/s模式下用程序?qū)崿F(xiàn)計(jì)劃任務(wù),一直是個(gè)不太好解決和管理的問(wèn)題,當(dāng)然可以采用ajax 計(jì)時(shí)器的方法模擬form端的timer事件。2009-11-11IIS和.NET(1.1/2.0)的安裝順序及錯(cuò)誤解決方法
安裝順序及錯(cuò)誤的解決方法:基于.net2.0的情況與基于.net1.1的情況,分別給予解決方法,遇到此問(wèn)題的朋友可以了解下,或許對(duì)你的學(xué)習(xí)有所幫助2013-02-02獲取遠(yuǎn)程網(wǎng)頁(yè)的內(nèi)容之一(downmoon原創(chuàng))
獲取遠(yuǎn)程網(wǎng)頁(yè)的內(nèi)容之一(downmoon原創(chuàng))...2007-03-03將Access數(shù)據(jù)庫(kù)中數(shù)據(jù)導(dǎo)入到SQL Server中的詳細(xì)方法實(shí)例
將Access數(shù)據(jù)庫(kù)中數(shù)據(jù)導(dǎo)入到SQL Server中的詳細(xì)方法實(shí)例,需要的朋友可以參考一下2013-03-03.Net彈性和瞬態(tài)故障處理庫(kù)Polly實(shí)現(xiàn)執(zhí)行策略
這篇文章介紹了.Net彈性和瞬態(tài)故障處理庫(kù)Polly實(shí)現(xiàn)執(zhí)行策略的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06