<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
刷貼文看到一篇 Go 記錄一次groutine通訊與context控制 看了一下需求背景,挺有意思的,琢磨了下.net core下的實現
專案中需要定期執行任務A來做一些輔助的工作,A的執行需要在超時時間內完成,如果本次執行超時了,那就不對本次的執行結果進行處理(即放棄這次執行)。同時A又依賴B,C兩個子任務的執行結果。B, C之間相互獨立,可以並行的執行。但無論B,C哪一個執行失敗或超時都會導致本次任務執行失敗。
public static class TaskHelper { // 有返回值 public static async Task<TResult> TimeoutAfter<TResult>(this Task<TResult> task, TimeSpan timeout) { using (var timeoutCancellationTokenSource = new CancellationTokenSource()) { var completedTask = await Task.WhenAny(task, Task.Delay(timeout, timeoutCancellationTokenSource.Token)); if (completedTask == task) { timeoutCancellationTokenSource.Cancel(); return await task; // Very important in order to propagate exceptions } else { throw new TimeoutException("The operation has timed out."); } } } // 無返回值 public static async Task TimeoutAfter(this Task task, TimeSpan timeout) { using (var timeoutCancellationTokenSource = new CancellationTokenSource()) { var completedTask = await Task.WhenAny(task, Task.Delay(timeout, timeoutCancellationTokenSource.Token)); if (completedTask == task) { timeoutCancellationTokenSource.Cancel(); await task; // Very important in order to propagate exceptions } else { throw new TimeoutException("The operation has timed out."); } } } }
這裡參考資料,寫了個拓展方法,主要用到CancellationTokenSource 與 Task.WhenAny
可以參考 C#中CancellationToken和CancellationTokenSource用法
可以參考 Task.WhenAny 方法
這裡需要特別注意,在非同步操作裡,如果非同步已經執行了,再執行取消時無效的,這是就需要我們自己在非同步委託中檢測了
知道了這兩個函數的作用,這段程式碼就很好理解了,通過Task.WhenAny返回最先完成的任務,如果是業務任務先完成,則呼叫timeoutCancellationTokenSource.Cancel()終止超時任務,等待業務任務結果,反之則直接丟擲timeout異常
[TestMethod] public async Task TestMethod1() { //A 任務必須在指定時間內完成,否則任務失敗 //A 任務依賴B,C任務,B,C可以並行,任何一個失敗,則A任務失敗 //A任務 try { //有效時間3s var timeOut = TimeSpan.FromSeconds(3); await Task.Run(async () => { List<Task<(string, bool)>> tasks = new List<Task<(string, bool)>>(); //B任務 tasks.Add(Task.Run(async () => { return ("B", await TestTask("B")); }).TimeoutAfter(timeOut)); //C任務 tasks.Add(Task.Run(async () => { return ("C", await TestTask("C")); }).TimeoutAfter(timeOut)); var res = await Task.WhenAll(tasks); //兩個任務,任何一個失敗,則A任務失敗 foreach (var item in res) { Console.WriteLine(item); } }).TimeoutAfter(timeOut); } catch (Exception ex) { Console.WriteLine("A任務執行超時了"); } //await Task.Delay(3000); } public async Task<bool> TestTask(string name) { var startTime = DateTime.Now; Console.WriteLine($"{startTime}---->{name}任務開始執行"); //隨機堵塞1-5s var t = new Random().Next(1, 5); await Task.Delay(t * 1000); var endTime = DateTime.Now; ; var time = (endTime - startTime).TotalSeconds; //亂數,模擬業務是否成功 var res = new Random().Next(1, 10); Console.WriteLine($"{endTime}---->{name}任務執行完畢,耗時{time} s"); return res <= 7; }
故事在這裡就結束了嗎? 顯然沒有,這麼簡單也沒必要水一篇部落格了
我們能做到在3s內響應結果,也算基本上滿足了需求,那超時的子任務,是否會繼續執行呢?
仔細看程式碼,就算超時,也是停止的Task.Delay() 這個執行緒,與業務執行緒沒有半毛錢關係,那業務執行緒肯定會繼續執行
眼尖的同學已經看到最後一張圖,B任務執行了3.0076088s,按道理B任務是已經超時了,這段話是不會輸出的,那如果我讓主執行緒晚點退出,那超時的子執行緒是否能正常執行, //await Task.Delay(3000); 將這段程式碼取消註釋,再來觀看結果
有沒有一種被欺騙的感覺,寫了一個假的超時時間,哈哈哈哈.....
這裡需要特別注意,在非同步操作裡,如果非同步已經執行了,再執行取消時無效的,這是就需要我們自己在非同步委託中檢測了
如果寫了一個死迴圈的task,那後果將不堪設想,這個時候,就需要慎重了,在使用多執行緒取消令牌的時候,除了需要執行Cancel()方法,還需要在子任務內自己捕獲CancellationTokenSource.Token.ThrowIfCancellationRequested()
到此這篇關於一次.net core非同步執行緒設定超時時間的文章就介紹到這了,更多相關.net core非同步執行緒設定超時時間內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45