.NET并發(fā)編程-異步編程模型下
祝福所有低調(diào)善良的技術(shù)人
本系列學習在.NET中的并發(fā)并行編程模式,實戰(zhàn)技巧
本小節(jié)開始學習基于任務(wù)的函數(shù)式并行。本系列保證最少代碼呈現(xiàn)量,雖然talk is cheap, show me the code被奉為圭臬,我的學習習慣是,只學習知識點,代碼不在當下立馬要用的時候不會認真去讀的,更何況在大多時候在手機閱讀更不順暢。
上一小節(jié)介紹了.NET中的異步支持,以及任務(wù)異步模型,異步的取消等。本小節(jié)繼續(xù)介紹下異步的重試和錯誤處理。
1、異步重試
異步請求有時會因為網(wǎng)絡(luò)原因等到導致任務(wù)失敗,重試也許就好了,因為對于任務(wù)可以指定次數(shù)的重試,兩次嘗試之間指定時間間隔。
public static async Task<T> Retry<T>(Func<Task<T>> task, int retries,TimeSpan delay, CancellationToken cts = default(CancellationToken)) =>await task().ContinueWith(async innerTask =>{cts.ThrowIfCancellationRequested();if (innerTask.Status != TaskStatus.Faulted)return innerTask.Result;if (retries == 0)throw innerTask.Exception ?? throw new Exception();await Task.Delay(delay, cts);return await Retry(task, retries - 1, delay, cts);}).Unwrap()
Retry異步操作,我們將此方法放在AsyncEx異步擴展靜態(tài)類中。ThrowIfCancellationRequested檢查下是否手動取消了,然后任務(wù)成功就返回,任務(wù)失敗就延遲指定時間啟動任務(wù),遞減重試次數(shù)。知道重試次數(shù)耗盡拋出異常。
下面是一個調(diào)用實例:
string stockHistory =await AsyncEx.Retry(() => DownloadStockHistory(symbol), 5, TimeSpan.FromSeconds(2));
2、錯誤處理
重試是一種錯誤處理機制。重試一直不行呢,就需要切換任務(wù)函數(shù)執(zhí)行。使用Otherwise組合器接收兩個任務(wù),如果第一個任務(wù)失敗就執(zhí)行第二個任務(wù)。通過Status判斷任務(wù)成功與否。
public static Task<T> Otherwise<T>(this Task<T> task, Func<Task<T>> orTask) =>task.ContinueWith(async innerTask =>{if (innerTask.Status == TaskStatus.Faulted) return await orTask();return await Task.FromResult<T>(innerTask.Result);}).Unwrap();
調(diào)用實例如下:
Image image = await Retry(async () =>await DownloadImageAsync("Bugghina001.jpg").Otherwise(async () =>await DownloadImageAsync("Bugghina002.jpg")),5, TimeSpan.FromSeconds(2));
上面靜態(tài)方法都是在AsyncEx靜態(tài)幫助類中,以獲得更加牢靠的任務(wù)執(zhí)行。
3、再說一句
平常我做桌面開發(fā)和少量的web后臺,用到并行的地方很少,我們體量沒有那么大,一直處理單線程模式中,腦子也是單核的。并行理解確實晦澀難懂,還是應(yīng)該慢慢熟練,走出安逸圈的過程必定痛苦的,現(xiàn)在有些許的明朗了。
前年說了很多函數(shù)組合器,下一節(jié)就重點看看這個,能給任務(wù)帶來多絲滑的體驗
祝福所有低調(diào)善良的技術(shù)人
簡單快樂
