最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

前言:

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

需求背景:

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

需求提煉:

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

.net里設(shè)置超時(shí)的 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.");
            }
        }
    }
}

這里參考資料,寫了個(gè)拓展方法,主要用到CancellationTokenSource 與 Task.WhenAny

可以參考 C#中CancellationToken和CancellationTokenSource用法

可以參考 Task.WhenAny 方法

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

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

測試代碼

    [TestMethod]
    public async Task TestMethod1()
    {
        //A 任務(wù)必須在指定時(shí)間內(nèi)完成,否則任務(wù)失敗
        //A 任務(wù)依賴B,C任務(wù),B,C可以并行,任何一個(gè)失敗,則A任務(wù)失敗
        //A任務(wù)
        try
        {
            //有效時(shí)間3s
            var timeOut = TimeSpan.FromSeconds(3);
            await Task.Run(async () =>
            {
                List<Task<(string, bool)>> tasks = new List<Task<(string, bool)>>();
                //B任務(wù)
                tasks.Add(Task.Run(async () =>
                {
                    return ("B", await TestTask("B"));
                }).TimeoutAfter(timeOut));

                //C任務(wù)
                tasks.Add(Task.Run(async () =>
                {
                    return ("C", await TestTask("C"));
                }).TimeoutAfter(timeOut));

                var res = await Task.WhenAll(tasks);

                //兩個(gè)任務(wù),任何一個(gè)失敗,則A任務(wù)失敗
                foreach (var item in res)
                {
                    Console.WriteLine(item);
                }

            }).TimeoutAfter(timeOut);

        }
        catch (Exception ex)
        {
            Console.WriteLine("A任務(wù)執(zhí)行超時(shí)了");
        }

        //await Task.Delay(3000);


    }

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

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

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

測試截圖

搞定收工

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

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

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

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

有沒有一種被欺騙的感覺,寫了一個(gè)假的超時(shí)時(shí)間,哈哈哈哈.....

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

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

總結(jié)

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

相關(guān)文章

  • asp.net 取消緩存相關(guān)問題說明

    asp.net 取消緩存相關(guān)問題說明

    asp.net 取消緩存相關(guān)問題說明,需要的朋友可以參考下。
    2009-11-11
  • .Net 調(diào)用存儲過程取到return的返回值

    .Net 調(diào)用存儲過程取到return的返回值

    存儲過程只能返回 int 類型,如果返回一個(gè)字符串 ,將會(huì)報(bào)類型轉(zhuǎn)化錯(cuò)誤,下面以示例介紹下如何取到return的值,需要的朋友可以參考下
    2014-08-08
  • ASP.NET驗(yàn)證碼(3種)

    ASP.NET驗(yàn)證碼(3種)

    這篇文章主要對ASP.NET實(shí)現(xiàn)三種驗(yàn)證碼的簡單實(shí)例進(jìn)行了介紹,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2015-08-08
  • ASP.NET MVC在基控制器中處理Session

    ASP.NET MVC在基控制器中處理Session

    這篇文章介紹了ASP.NET MVC在基控制器中處理Session的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-08-08
  • ASP.NET中的無刷新驗(yàn)證碼的開發(fā)(完整代碼)

    ASP.NET中的無刷新驗(yàn)證碼的開發(fā)(完整代碼)

    ASP.NET中的無刷新驗(yàn)證碼的開發(fā)(完整代碼),需要的朋友可以參考下。
    2010-09-09
  • linq中的分區(qū)操作符

    linq中的分區(qū)操作符

    這篇文章介紹了linq中的分區(qū)操作符,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • asp.net core3.1cookie和jwt混合認(rèn)證授權(quán)實(shí)現(xiàn)多種身份驗(yàn)證方案

    asp.net core3.1cookie和jwt混合認(rèn)證授權(quán)實(shí)現(xiàn)多種身份驗(yàn)證方案

    身份驗(yàn)證是確定用戶身份的過程。 授權(quán)是確定用戶是否有權(quán)訪問資源的過程。本文主要介紹了asp.net core3.1cookie和jwt混合認(rèn)證授權(quán)實(shí)現(xiàn)多種身份驗(yàn)證方案,感興趣的可以了解一下
    2021-09-09
  • Web.Config文件配置之限制上傳文件大小和時(shí)間的屬性配置

    Web.Config文件配置之限制上傳文件大小和時(shí)間的屬性配置

    在Web.Config文件中配置限制上傳文件大小與時(shí)間字符串時(shí),是在httpRuntime httpRuntime節(jié)中完成的,需要設(shè)置以下2個(gè)屬性:maxRequestLength屬性與ExecutionTimeout屬性,感興趣的朋友可以了解下,或許對你有所幫助
    2013-02-02
  • 如何為asp.net core添加protobuf支持詳解

    如何為asp.net core添加protobuf支持詳解

    這篇文章主要給大家介紹了關(guān)于如何為asp.net core添加protobuf支持的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-02-02
  • 基于.Net?Core認(rèn)證授權(quán)方案之JwtBearer認(rèn)證

    基于.Net?Core認(rèn)證授權(quán)方案之JwtBearer認(rèn)證

    這篇文章介紹了基于.Net?Core認(rèn)證授權(quán)方案之JwtBearer認(rèn)證,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06

最新評論

汪清县| 宜春市| 宁南县| 高唐县| 资兴市| 西畴县| 板桥市| 霍州市| 南召县| 邹城市| 临江市| 台北市| 鄢陵县| 镇安县| 永兴县| 故城县| 屏山县| 长宁县| 水富县| 中方县| 涟源市| 扎囊县| 张家港市| 宁晋县| 章丘市| 镇安县| 聂拉木县| 常山县| 桃源县| 家居| 土默特左旗| 宜阳县| 大理市| 双牌县| 肃南| 司法| 罗江县| 沂南县| 鄂托克前旗| 建湖县| 龙江县|