亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

一次.net?core異步線程設置超時時間的實戰(zhàn)記錄

 更新時間:2022年02月11日 15:56:01   作者:提伯斯  
這篇文章主要給大家介紹了關于.net?core異步線程設置超時時間的相關資料,文中通過實例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下

前言:

刷帖子看到一篇 Go 記錄一次groutine通信與context控制 看了一下需求背景,挺有意思的,琢磨了下.net core下的實現(xiàn)

需求背景:

項目中需要定期執(zhí)行任務A來做一些輔助的工作,A的執(zhí)行需要在超時時間內(nèi)完成,如果本次執(zhí)行超時了,那就不對本次的執(zhí)行結(jié)果進行處理(即放棄這次執(zhí)行)。同時A又依賴B,C兩個子任務的執(zhí)行結(jié)果。B, C之間相互獨立,可以并行的執(zhí)行。但無論B,C哪一個執(zhí)行失敗或超時都會導致本次任務執(zhí)行失敗。

需求提煉:

  • A任務必須在指定時間內(nèi)完成,否則任務失敗
  • A任務依賴B,C任務,B,C可以并行,任何一個失敗,則A任務失敗
  • A任務在超時時間內(nèi),是否需求記錄子任務執(zhí)行詳情(根據(jù)業(yè)務需求來定)

.net里設置超時的 Task

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 方法

這里需要特別注意,在異步操作里,如果異步已經(jīng)執(zhí)行了,再執(zhí)行取消時無效的,這是就需要我們自己在異步委托中檢測了

知道了這兩個函數(shù)的作用,這段代碼就很好理解了,通過Task.WhenAny返回最先完成的任務,如果是業(yè)務任務先完成,則調(diào)用timeoutCancellationTokenSource.Cancel()終止超時任務,等待業(yè)務任務結(jié)果,反之則直接拋出timeout異常

測試代碼

    [TestMethod]
    public async Task TestMethod1()
    {
        //A 任務必須在指定時間內(nèi)完成,否則任務失敗
        //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任務執(zhí)行超時了");
        }

        //await Task.Delay(3000);


    }

    public async Task<bool> TestTask(string name) 
    {
        var startTime = DateTime.Now;
        Console.WriteLine($"{startTime}---->{name}任務開始執(zhí)行");
        //隨機堵塞1-5s
        var t = new Random().Next(1, 5);
        await Task.Delay(t * 1000);

        var endTime = DateTime.Now; ;
        var time = (endTime - startTime).TotalSeconds;

        //隨機數(shù),模擬業(yè)務是否成功
        var res = new Random().Next(1, 10);
        Console.WriteLine($"{endTime}---->{name}任務執(zhí)行完畢,耗時{time} s");
        return res <= 7;
    }

測試截圖

搞定收工

故事在這里就結(jié)束了嗎? 顯然沒有,這么簡單也沒必要水一篇博客了

我們能做到在3s內(nèi)響應結(jié)果,也算基本上滿足了需求,那超時的子任務,是否會繼續(xù)執(zhí)行呢?

仔細看代碼,就算超時,也是停止的Task.Delay() 這個線程,與業(yè)務線程沒有半毛錢關系,那業(yè)務線程肯定會繼續(xù)執(zhí)行

眼尖的同學已經(jīng)看到最后一張圖,B任務執(zhí)行了3.0076088s,按道理B任務是已經(jīng)超時了,這段話是不會輸出的,那如果我讓主線程晚點退出,那超時的子線程是否能正常執(zhí)行, //await Task.Delay(3000); 將這段代碼取消注釋,再來觀看結(jié)果

有沒有一種被欺騙的感覺,寫了一個假的超時時間,哈哈哈哈.....

這里需要特別注意,在異步操作里,如果異步已經(jīng)執(zhí)行了,再執(zhí)行取消時無效的,這是就需要我們自己在異步委托中檢測了

如果寫了一個死循環(huán)的task,那后果將不堪設想,這個時候,就需要慎重了,在使用多線程取消令牌的時候,除了需要執(zhí)行Cancel()方法,還需要在子任務內(nèi)自己捕獲CancellationTokenSource.Token.ThrowIfCancellationRequested()

總結(jié)

到此這篇關于一次.net core異步線程設置超時時間的文章就介紹到這了,更多相關.net core異步線程設置超時時間內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • ASP.NET筆記之廣告控件的使用方法

    ASP.NET筆記之廣告控件的使用方法

    本篇文章小編為大家介紹,ASP.NET筆記之廣告控件的使用方法,需要的朋友參考下
    2013-04-04
  • ASP.NET Get和Post兩種提交方法淺析

    ASP.NET Get和Post兩種提交方法淺析

    表單form的提交有兩種方式,一種是get的方法,一種是post 的方法.看下面代碼,理解ASP.NET Get和Post兩種提交的區(qū)別:
    2013-03-03
  • .NET實現(xiàn)API版本控制

    .NET實現(xiàn)API版本控制

    這篇文章介紹了.NET實現(xiàn)API版本控制的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-07-07
  • asp.net利用母版制作頁腳效果

    asp.net利用母版制作頁腳效果

    這篇文章主要為大家詳細介紹了asp.net利用母版制作頁腳效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • .NET使用Collections.Pooled提升性能優(yōu)化的方法

    .NET使用Collections.Pooled提升性能優(yōu)化的方法

    這篇文章主要介紹了.NET使用Collections.Pooled性能優(yōu)化的方法,今天要給大家分享類庫Collections.Pooled,它是通過池化內(nèi)存來達到降低內(nèi)存占用和GC的目的,另外也會帶大家看看源碼,為什么它會帶來這些性能提升,一起通過本文學習下吧
    2022-05-05
  • ASP.NET Core MVC如何實現(xiàn)運行時動態(tài)定義Controller類型

    ASP.NET Core MVC如何實現(xiàn)運行時動態(tài)定義Controller類型

    這篇文章主要介紹了ASP.NET Core MVC如何實現(xiàn)運行時動態(tài)定義Controller類型,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-06-06
  • Linux服務器下利用Docker部署.net Core項目的全過程

    Linux服務器下利用Docker部署.net Core項目的全過程

    這篇文章主要給大家介紹了關于在Linux服務器下利用Docker部署.net Core項目的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用.net Core具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-07-07
  • VS2010/VS2013項目創(chuàng)建 ADO.NET連接mysql/sql server詳細步驟

    VS2010/VS2013項目創(chuàng)建 ADO.NET連接mysql/sql server詳細步驟

    這篇文章主要介紹了VS2010/VS2013項目創(chuàng)建,及ADO.NET連接mysql/sql server詳細步驟,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • EF?Core基礎入門教程

    EF?Core基礎入門教程

    這篇文章介紹了EF?Core的基礎入門教程,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-04-04
  • asp.net GridView中超鏈接的使用(帶參數(shù))

    asp.net GridView中超鏈接的使用(帶參數(shù))

    在GridView中,點擊鏈接列跳轉(zhuǎn)到指定頁面的實現(xiàn)代碼,需要的朋友可以參考下。
    2010-03-03

最新評論