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

C#中Task.WhenAll和Task.WhenAny的使用與區(qū)別小結(jié)

 更新時間:2025年12月28日 10:28:13   作者:無風(fēng)聽海  
Task.WhenAll和Task.WhenAny是用于組合多個Task完成信號的工具,本文主要介紹了C#中Task.WhenAll和Task.WhenAny的使用與區(qū)別小結(jié),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

一、先給終極結(jié)論

Task.WhenAll 和 Task.WhenAny 都不是執(zhí)行器,而是“完成信號的組合器”。
它們:

  • ? 不創(chuàng)建線程
  • ? 不調(diào)度任務(wù)
  • ? 不產(chǎn)生并發(fā)
  • ? 只監(jiān)聽 Task 的完成

并發(fā)發(fā)生在 Task 被“創(chuàng)建/啟動”的那一刻,而不是 WhenAll/WhenAny。

二、兩者的本質(zhì)模型(抽象層)

1、 Task.WhenAll —— “全部完成門閂(AND Gate)”

T1 ─┐
T2 ─┼─? [ All Completed ] ─? Completed Task
T3 ─┘

語義:

  • 所有 Task 完成 → WhenAll 完成
  • 任一 Task 失敗 → WhenAll 失?。ǖ缘人薪Y(jié)束)

2、 Task.WhenAny —— “第一個完成門閂(OR Gate)”

T1 ─┐
T2 ─┼─? [ First Completed ] ─? Completed Task<Task>
T3 ─┘

語義:

  • 第一個完成者勝出
  • 其他 Task 不受影響,繼續(xù)運行

三、底層實現(xiàn)原理(核心機制)

1、WhenAll 的內(nèi)部機制(簡化版)

  • 對每個 Task 注冊 continuation

  • 使用一個 原子計數(shù)器(remaining)

  • 每完成一個 Task:

    • 記錄狀態(tài)(成功 / 失敗 / 取消)
    • Interlocked.Decrement(remaining)
  • 當(dāng) remaining == 0

    • 設(shè)置 WhenAll Task 的最終狀態(tài)

?? 沒有線程等待,完全事件驅(qū)動

2、WhenAny 的內(nèi)部機制(簡化版)

對每個 Task 注冊 continuation

第一個完成的 Task:

  • 調(diào)用 TrySetResult(task)

后續(xù)完成者:

  • 直接忽略

?? 只有一個能“贏”,沒有計數(shù)器

3、為什么 WhenAny 返回Task<Task>?

  • 外層 Task:表示“誰先完成”
  • 內(nèi)層 Task:表示“完成的那個任務(wù)本身”

WhenAny 返回的是“勝者句柄”,不是結(jié)果

四、執(zhí)行與調(diào)度層面的關(guān)鍵差異

維度WhenAllWhenAny
等待策略全部第一個
返回類型Task / Task<T[]>Task
是否阻塞線程??
continuation 數(shù)量NN
內(nèi)部同步原子計數(shù)CAS / TrySet
并發(fā)控制??

二者都只做“信號組合”,不做“任務(wù)調(diào)度”

五、異常語義(非常重要)

1、 WhenAll 的異常規(guī)則

  • 所有 Task 都會執(zhí)行到結(jié)束

  • 如果有異常:

    • 內(nèi)部保存 AggregateException

    • await WhenAll 時:

      • 拋出 第一個異常
      • 其他異常仍可從各 Task 中取
try
{
    await Task.WhenAll(tasks);
}
catch
{
    var all = tasks
        .Where(t => t.IsFaulted)
        .SelectMany(t => t.Exception!.InnerExceptions);
}

2、 WhenAny 的異常規(guī)則

  • 如果“第一個完成的 Task”失?。?/p>

    • await completedTask 會直接拋異常
  • 其他 Task 的異常:

    • 不會被觀察
    • 必須手動處理,否則可能變成未觀察異常

?? WhenAny + 異常 = 高風(fēng)險組合

六、取消語義(常被誤解)

1、WhenAll

  • 如果任一 Task 被取消:

    • WhenAll 最終可能是 Canceled
  • 但:

    • 不會主動取消其他 Task

2、 WhenAny

  • 不會取消任何 Task
  • 取消必須由你顯式觸發(fā)
var winner = await Task.WhenAny(tasks);
cts.Cancel(); // 你自己的責(zé)任

七、性能特征(底層視角)

1、 WhenAll / WhenAny 本身的成本

  • 少量對象分配
  • N 個 continuation
  • 原子操作 / CAS

?? 幾乎可以忽略

2、真正的性能瓶頸來自:

  • Task 創(chuàng)建方式
  • IO / CPU 本身
  • Task.Run / ThreadPool 使用
  • 并發(fā)規(guī)模失控

八、典型使用范式(工程級)

1、 WhenAll —— 并發(fā)聚合(最常用)

var t1 = GetUserAsync();
var t2 = GetOrdersAsync();

await Task.WhenAll(t1, t2);

return new
{
    User = await t1,
    Orders = await t2
};

適用場景

  • 多個獨立 IO
  • 聚合響應(yīng)
  • Web API

2、 WhenAny —— 競速 / 超時 / 降級

超時模式

var work = DoWorkAsync();
var timeout = Task.Delay(2000);

if (await Task.WhenAny(work, timeout) == timeout)
    throw new TimeoutException();

await work;

主備切換

var tasks = new[]
{
    CallPrimaryAsync(),
    CallSecondaryAsync()
};

var winner = await Task.WhenAny(tasks);
return await winner;

?? 記得取消失敗者

九、常見錯誤總結(jié)

? 把 WhenAll 當(dāng)“并行器”
? 在循環(huán)里直接 await(偽并發(fā))
? WhenAny 后忽略未完成 Task
? WhenAll + Task.Run(Web)
? 忽略異常和取消

十、設(shè)計層面的黃金準(zhǔn)則

并發(fā) = Task 創(chuàng)建時機
組合 = WhenAll / WhenAny
調(diào)度 = ThreadPool / Parallel

WhenAll / WhenAny 決定“怎么等”,
而不是“怎么跑”。

十一、一句話終極總結(jié)

Task.WhenAll 是一個原子計數(shù)器驅(qū)動的完成門閂
Task.WhenAny 是一個 CAS 驅(qū)動的競速門閂

它們本身幾乎“沒有重量”,
但決定了整個 async 架構(gòu)的形狀。

到此這篇關(guān)于C#中Task.WhenAll和Task.WhenAny的使用與區(qū)別小結(jié)的文章就介紹到這了,更多相關(guān)C# Task.WhenAll和Task.WhenAny內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

岑巩县| 清丰县| 北宁市| 普兰县| 临高县| 赣州市| 沾益县| 西乡县| 洛隆县| 左贡县| 咸丰县| 绥江县| 安义县| 舒兰市| 江山市| 龙海市| 阿拉善盟| 库车县| 崇阳县| 寿宁县| 尚义县| 临湘市| 温泉县| 民权县| 沙河市| 郁南县| 英吉沙县| 彭山县| 化德县| 罗甸县| 河北区| 宿州市| 高州市| 大荔县| 正蓝旗| 鄄城县| 平果县| 云南省| 开远市| 张北县| 承德市|