国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

并發(fā)編程 --- 異步方法的異常處理

這篇具有很好參考價值的文章主要介紹了并發(fā)編程 --- 異步方法的異常處理。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

引言

現(xiàn)在模擬一個異步方法拋出了異常:

public static async Task ThrowAfter(int ms, string message)
{
    await Task.Delay(ms);
    throw new Exception(message);
}

思考一下, DontHandle() 方法是否能夠捕獲到異常?

public static void DontHandle()
{
    try
    {
        ThrowAfter(1000, "first");
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }

}

答案是:不會捕獲到異常!

因為 DontHandle() 方法在 ThrowAfter() 方法拋出異常之前,就已經(jīng)執(zhí)行完畢。

異步方法的異常處理

那么上述代碼怎么才能捕獲到異常呢?

若想要捕獲異常則必須通過 await 關(guān)鍵字等待 ThrowAfter() 方法執(zhí)行完成。

將上文中的代碼段進行修改:

public static async void HandleoOnError()
{
    try
    {
        await ThrowAfter(1000, "first");
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

結(jié)果就會輸出:

first

多個異步方法的異常處理

如果調(diào)用兩個異步方法,每個都會拋出異常,該如何處理呢?

我們可以這樣寫:

public static async void StartTwoTasks()
{
    try
    {
        await ThrowAfter(1000, "first");
        await ThrowAfter(1000, "second");
        Console.WriteLine("StartTwoTasks is Complate");
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

思考一下輸出是什么?

答案是:

first

并沒有預(yù)想中的兩個異常都捕獲打印出來,也沒有看到“StartTwoTasks is Complate”這句話打印出來。因為使用 await 關(guān)鍵字之后,兩次調(diào)用 ThrowAfter() 方法就變成了同步執(zhí)行,捕獲到第一次的異常之后直接進入到 catch 代碼段,不再執(zhí)行后續(xù)代碼。

可以嘗試解決這個問題,使用 Task.WhenAll() 方法,該方法不管任務(wù)是否拋出異常,都會等到兩個任務(wù)完成。如下代碼:

public static async void StartTwoTasksParallel()
{
    try
    {
        Task t1 = ThrowAfter(1000, "first");
        Console.WriteLine("t1 is Complate");
        Task t2 = ThrowAfter(1000, "second");
        Console.WriteLine("t2 is Complate");
        await Task.WhenAll(t2, t1);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

輸出:

t1 is Complate
t2 is Complate
second

從輸出可以看出來,使用 WhenAll() 方法,兩個任務(wù)都是執(zhí)行完成的,但是,捕獲異常只能捕獲 WhenAll()方法參數(shù)中,排在最前面的,且第一個拋出異常的任務(wù)的消息,

上述方式有缺陷,只能拋出一個異常的任務(wù)的消息,可以將上面的方式再進化一下,如下代碼:

public static async void StartTwoTasksParallelEx()
{
    Task t1 = null;
    Task t2 = null;
    try
    {
        t1 = ThrowAfter(1000, "first");
        t2 = ThrowAfter(1000, "second");
        await Task.WhenAll(t2, t1);

    }
    catch (Exception ex)
    {
        if (t1.IsFaulted)
        {
            Console.WriteLine(t1.Exception.InnerException.Message);
        }

        if (t2.IsFaulted)
        {
            Console.WriteLine(t2.Exception.InnerException.Message);
        }
    }
}

輸出:

first
second

try/catch 代碼塊外聲明任務(wù)變量t1、t2,使他們可以在 try/catch 塊內(nèi)訪問,在這里,使用了IsFaulted 屬性,檢查任務(wù)的狀態(tài),若IsFaulted 屬性為 true ,則表示該任務(wù)出現(xiàn)異常,就可以使用 Task.Exception.InnerException 訪問異常本身。

使用AggregateException信息

除了上述方式外,還有一種更好的獲取所有任務(wù)的異常信息的方式,Task.WhenAll() 方法返回的結(jié)果其實也是一個 Task 對象,而 Task 有一個 Exception 屬性,它的類型是 AggregateException,是 Exception的一個派生類,AggregateException 類有一個 InnerExceptions 屬性(異常集合,包含 Task.WhenAll() 方法列表中所有異常任務(wù)的異常信息)。

有了這個屬性則可以輕松遍歷所有異常。如下代碼:

public static async void StartTwoTasksParallelEx2()
{
    Task t3 = null;
    try
    {
        Task t1 = ThrowAfter(1000, "first");
        Task t2 = ThrowAfter(1000, "second");
        await (t3 = Task.WhenAll(t2, t1));

    }
    catch (Exception ex)
    {
        foreach (var item in t3.Exception.InnerExceptions)
        {
            Console.WriteLine("InnerException:" + item.Message);
        }
    }
}

輸出:

InnerException:second
InnerException:first

總結(jié)

除了前面提到的異步方法異常處理的基本知識點,以下是一些進階的異常處理技巧:

  • 在異步方法中,如果需要將異常傳遞給調(diào)用方,請不要直接拋出異常。相反,應(yīng)該使用 throw 關(guān)鍵字將異常包裝在一個 TaskValueTask 對象中,并將其返回給調(diào)用方。這可以避免在異步操作中丟失異常信息。

  • 如果需要在異步方法中處理多個異常,可以使用 catch 塊來捕獲不同類型的異常,并根據(jù)需要執(zhí)行不同的處理操作。還可以使用 finally 塊來執(zhí)行清理操作,例如釋放資源或恢復(fù)狀態(tài)。

  • 如果需要在異步方法中執(zhí)行一些異步操作,并且這些操作都必須成功才能繼續(xù)執(zhí)行下一步操作,那么可以使用 Task.WhenAll 方法來等待所有異步操作完成。如果任何一個異步操作失敗,WhenAll 方法將返回一個 AggregateException 對象,其中包含所有失敗的異常。

  • 如果需要在異步方法中執(zhí)行多個異步操作,并且這些操作中的任何一個失敗都將導(dǎo)致整個操作失敗,那么可以使用 Task.WhenAny 方法來等待第一個異步操作完成。如果第一個操作失敗,WhenAny 方法將返回一個 AggregateException 對象,其中包含第一個失敗的異常。

  • 如果需要在異步方法中進行錯誤處理并且希望能夠獲取更多有關(guān)異常的信息,可以使用 ExceptionDispatchInfo 類。這個類可以捕獲異常并將其存儲在一個對象中,然后在需要時重新拋出異常。這可以幫助在異步操作中保留異常信息,并將其傳遞給調(diào)用方。

總之,在異步方法中處理異常時,需要注意一些細節(jié)和技巧,例如正確處理異常、捕獲多個異常、等待多個異步操作、以及使用 ExceptionDispatchInfo 類來捕獲異常。掌握這些處理技巧可以幫助編寫更可靠、更健壯的異步代碼。文章來源地址http://www.zghlxwxcb.cn/news/detail-617086.html

到了這里,關(guān)于并發(fā)編程 --- 異步方法的異常處理的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Python異步編程之web框架 異步vs同步 Redis并發(fā)對比

    Python異步編程之web框架 異步vs同步 Redis并發(fā)對比

    主題: 比較異步框架和同步框架在RedisIO操作的性能差異 python版本 :python 3.8 數(shù)據(jù)庫 :redis 5.0.7 壓測工具 :locust web框架 :同步:flask 異步:starlette 請求并發(fā)量 : 模擬10個用戶 服務(wù)器配置 : Intel(R) i7-12700F 客戶端配置 :Intel(R) i7-8700 3.20GHz flask是python中輕量級web框架,特點是靈

    2024年02月10日
    瀏覽(29)
  • 【文末送書】Python高并發(fā)編程:探索異步IO和多線程并發(fā)

    【文末送書】Python高并發(fā)編程:探索異步IO和多線程并發(fā)

    歡迎關(guān)注博主 Mindtechnist 或加入【智能科技社區(qū)】一起學(xué)習(xí)和分享Linux、C、C++、Python、Matlab,機器人運動控制、多機器人協(xié)作,智能優(yōu)化算法,濾波估計、多傳感器信息融合,機器學(xué)習(xí),人工智能等相關(guān)領(lǐng)域的知識和技術(shù)。搜索關(guān)注公粽號 《機器和智能》 發(fā)送“刷題寶

    2024年02月15日
    瀏覽(22)
  • 并發(fā)編程 | 從Future到CompletableFuture - 簡化 Java 中的異步編程

    在并發(fā)編程中,我們經(jīng)常需要處理多線程的任務(wù),這些任務(wù)往往具有依賴性,異步性,且需要在所有任務(wù)完成后獲取結(jié)果。Java 8 引入了 CompletableFuture 類,它帶來了一種新的編程模式,讓我們能夠以函數(shù)式編程的方式處理并發(fā)任務(wù),顯著提升了代碼的可讀性和簡潔性。 在這篇

    2024年02月13日
    瀏覽(27)
  • Python異步編程高并發(fā)執(zhí)行爬蟲采集,用回調(diào)函數(shù)解析響應(yīng)

    Python異步編程高并發(fā)執(zhí)行爬蟲采集,用回調(diào)函數(shù)解析響應(yīng)

    異步技術(shù)是Python編程中對提升性能非常重要的一項技術(shù)。在實際應(yīng)用,經(jīng)常面臨對外發(fā)送網(wǎng)絡(luò)請求,調(diào)用外部接口,或者不斷更新數(shù)據(jù)庫或文件等操作。 這這些操作,通常90%以上時間是在等待,如通過REST, gRPC向服務(wù)器發(fā)送請求,通??赡艿却龓资撩胫翈酌?,甚至更長。如

    2024年02月08日
    瀏覽(24)
  • Python異步編程之web框架 異步vs同步 數(shù)據(jù)庫IO任務(wù)并發(fā)支持對比

    Python異步編程之web框架 異步vs同步 數(shù)據(jù)庫IO任務(wù)并發(fā)支持對比

    主題: 比較異步框架和同步框架在數(shù)據(jù)庫IO操作的性能差異 python版本 :python 3.8 數(shù)據(jù)庫 :mysql 8.0.27 (docker部署) 壓測工具 :locust web框架 :同步:flask 異步:starlette 請求并發(fā)量 : 模擬10個用戶 服務(wù)器配置 : Intel(R) i7-12700F 客戶端配置 :Intel(R) i7-8700 3.20GHz python中操作數(shù)據(jù)庫通常

    2024年02月08日
    瀏覽(31)
  • ARMv8-AArch64 的異常處理模型詳解之異常處理詳解(同步異常和異步異常的分析和處理)

    ARMv8-AArch64 的異常處理模型詳解之異常處理詳解(同步異常和異步異常的分析和處理)

    在文章ARMv8-AArch64 的異常處理模型詳解之異常類型 Exception types中提到過,同步異常是處理器在執(zhí)行指令時產(chǎn)生的異常,是一種精確的,可以具體定位到是哪條指令導(dǎo)致異常的產(chǎn)生。下面筆者將介紹三個用于定位并分析同步異常產(chǎn)生的寄存器。 在文章ARMv8-AArch64 的異常處理模型

    2024年03月27日
    瀏覽(23)
  • Vue公共loading升級版(處理并發(fā)異步差時響應(yīng))

    公共loading是項目系統(tǒng)中很常見的場景,處理方式也不外乎三個步驟: 1.通過全局狀態(tài)管理定義狀態(tài)值(vuex、pinia等)。 2.在程序主入口監(jiān)聽狀態(tài)值變化,從而展示/隱藏laoding動畫。 3.在請求和相應(yīng)攔截器中變更狀態(tài)值。 第一二步驟處理大同小異,但在第三步中,網(wǎng)上很多博文

    2024年02月05日
    瀏覽(17)
  • 【并發(fā)編程】線程池多線程異步去分頁調(diào)用其他服務(wù)接口獲取海量數(shù)據(jù)

    前段時間在做一個數(shù)據(jù)同步工具,其中一個服務(wù)的任務(wù)是調(diào)用A服務(wù)的接口,將數(shù)據(jù)庫中指定數(shù)據(jù)請求過來,交給kafka去判斷哪些數(shù)據(jù)是需要新增,哪些數(shù)據(jù)是需要修改的。 剛開始的設(shè)計思路是,,我創(chuàng)建多個服務(wù)同時去請求A服務(wù)的接口,每個服務(wù)都請求到全量數(shù)據(jù),由于這些

    2024年02月13日
    瀏覽(32)
  • Java高并發(fā)系列: 使用wait - notify實現(xiàn)高效異步方法

    Java高并發(fā)系列: 使用wait - notify實現(xiàn)高效異步方法

    在項目開發(fā)中, 通常會有異步執(zhí)行操作, 例如: 提交一個異步清空一系列數(shù)據(jù)庫中ID = ${_id} 的記錄, 這個時候通常的做法是主線程將任務(wù)添加到一個異步隊列中, 后臺維護一個線程不斷地 循環(huán) 掃描這個隊列, 如果有需要執(zhí)行的任務(wù), 則執(zhí)行相應(yīng)的邏輯. 如下圖所示: 代碼實現(xiàn)如下

    2024年02月09日
    瀏覽(29)
  • 【并發(fā)編程】自研數(shù)據(jù)同步工具的優(yōu)化:創(chuàng)建線程池多線程異步去分頁調(diào)用其他服務(wù)接口獲取海量數(shù)據(jù)

    前段時間在做一個數(shù)據(jù)同步工具,其中一個服務(wù)的任務(wù)是調(diào)用A服務(wù)的接口,將數(shù)據(jù)庫中指定數(shù)據(jù)請求過來,交給kafka去判斷哪些數(shù)據(jù)是需要新增,哪些數(shù)據(jù)是需要修改的。 剛開始的設(shè)計思路是,,我創(chuàng)建多個服務(wù)同時去請求A服務(wù)的接口,每個服務(wù)都請求到全量數(shù)據(jù),由于這些

    2024年02月12日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包