在.Net和C#中運作異步代碼相當簡單,因為我們有時候需要取消正在進行的異步操作,通過本文,可以掌握 通過CancellationToken取消任務(包括non-cancellable任務)。
Task 表示無傳回值的異步操作, 泛型版本Task<TResult>表示有傳回值的異步操作, 現在async/await 文法糖大大簡化了我們編寫異步程式的難度。
建立一個長時間運作的操作:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
View Code
簡單異步調用代碼:
因為一些原因我們會取消異步操作:
操作耗時較長,堵塞了其他正常請求;
不願意再等待執行結果了,手動取消
其中關注
類CancellationTokenSource:給CancellationToken發出取消通知
結構體CancellationToken: 取消操作的通知。
CancellationToken結構體相當于打入在異步操作内部的楔子,随時等候CancellationTokenSource 發出的取消通知。
定義異步方法時候設定 CancelletionToken參數
那麼這個異步方法即是Cancellable 的異步方法
在長時間運作的操作中監測 IsCancellationRequested方法 (目前是否發生取消指令),這裡我傾向去包裝一個TaskCanceledException異常類(給上層方法調用者更多處理的可能性); 當然可以調用ThrowIfCancellationRequested方法抛出OperationCanceledException異常。
發送取消通知
操縱以上CancellationToken狀态的對象是 CancellationTokenSource,這個對象是取消操作的指令釋出者。
手動取消操作
有時候,部分第三方異步操作代碼并不是可取消的,也就是以上長時間運作的異步操作LongRunningCancellableOperation(int loop, CancellationToken cancellationToken) 并不支援CancellationToken ,相當于不允許打入楔子。
這時我們怎樣取消 這樣的non-Cancellable 任務?
可考慮利用 Task.WhenAny( params tasks) 操作曲線取消:
利用TaskCompletionSource 注冊異步可取消任務
等待待non-cancellable 操作和以上建立的 異步取消操作
像上面代碼一樣執行取消指令 :
大多數情況下,我們不需要編寫自定義可取消任務,因為我們隻需要使用現有API。但要知道它是如何在幕後工作總是好的。
+ https://johnthiriet.com/cancel-asynchronous-operation-in-csharp/
+ https://stackoverflow.com/questions/4238345/asynchronously-wait-for-taskt-to-complete-with-timeout
+ https://github.com/App-vNext/Polly/wiki/Timeout
本文來自部落格園,作者:{有态度的馬甲},轉載請注明原文連結:https://www.cnblogs.com/JulianHuang/p/10572840.html
歡迎關注我的原創技術、職場公衆号, 加好友談天說地,一起進化