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

C# Task.WhenAll的用法小結(jié)

 更新時間:2025年11月07日 10:38:23   作者:熊思宇  
C# 中的 Task.WhenAll 方法是一種用于并行執(zhí)行多個任務并等待它們?nèi)客瓿傻母咝Х绞?本文就來詳細的介紹一下C# Task.WhenAll的用法小結(jié),感興趣的可以了解一下

一、簡介

C# 中的 Task.WhenAll 方法是一種用于并行執(zhí)行多個任務并等待它們?nèi)客瓿傻母咝Х绞?。它接收一個任務數(shù)組或任務集合作為參數(shù),并返回一個表示所有任務都已完成的新任務。當調(diào)用 Task.WhenAll 返回的任務的 Wait 方法或 Result 屬性時,程序會阻塞,直到所有傳入的任務都已完成。如果任何一個傳入的任務失敗并拋出異常,Task.WhenAll 返回的任務也會以異常結(jié)束,從而允許開發(fā)者集中處理錯誤。這種方法在需要并行處理多個獨立任務并等待它們?nèi)客瓿蓵r非常有用,能夠顯著提高應用程序的性能和響應速度。

Task.WhenAll 和 Task.WaitAll 都是 C# 中用于處理并發(fā)任務的方法,但它們之間存在顯著的不同。以下是對兩者的具體比較:

異步與同步

  • Task.WhenAll:是異步的,不會阻塞調(diào)用它的線程。它返回一個表示所有輸入任務聯(lián)合完成的新 Task 對象。
  • Task.WaitAll:是同步的,會阻塞調(diào)用它的線程,直到所有任務都完成為止。它沒有返回值。

使用場景

  • Task.WhenAll:適用于需要并行執(zhí)行多個任務,并且不想阻塞當前線程的場景。它允許在等待任務完成的同時,執(zhí)行其他操作。
  • Task.WaitAll:適用于需要等待所有任務都完成才能繼續(xù)執(zhí)行的場景,但它會阻塞當前線程,因此不適合需要保持線程響應性的應用。

異常處理

  • Task.WhenAll:當任何一個輸入任務拋出異常時,它會立即返回一個處于出錯狀態(tài)的 Task 對象。開發(fā)者可以通過檢查返回的 Task 對象來處理異常。
  • Task.WaitAll:會一直等待所有任務完成,包括在其中一個任務拋出異常時。異常會被捕獲并包裝在 AggregateException 中,需要開發(fā)者處理這個異常。

返回值與結(jié)果獲取

  • Task.WhenAll:返回一個新的 Task 對象,該對象的 Result 屬性是一個包含所有輸入任務結(jié)果的數(shù)組(如果輸入任務有返回值)。如果輸入任務沒有返回值,結(jié)果數(shù)組的元素類型為 void。
  • Task.WaitAll:沒有返回值,它僅用于等待所有任務完成。

官方的文檔:

點擊跳轉(zhuǎn)

官方的解釋:

創(chuàng)建一個任務,該任務將在所有提供的任務完成時完成。

主要接口:

WhenAll(IEnumerable<Task>) 創(chuàng)建一個任務,該任務將在可枚舉集合中的所有 Task 對象完成時完成
WhenAll(ReadOnlySpan<Task>) 創(chuàng)建一個任務,該任務將在所有提供的任務完成時完成
WhenAll(Task[]) 創(chuàng)建一個任務,該任務將在數(shù)組中的所有 Task 對象完成時完成
WhenAll<TResult>(ReadOnlySpan<Task<TResult>>) 創(chuàng)建一個任務,該任務將在所有提供的任務完成時完成
WhenAll<TResult>(IEnumerable<Task<TResult>>)創(chuàng)建一個任務,該任務將在可枚舉集合中的所有 Task<TResult> 對象完成時完成
WhenAll<TResult>(Task<TResult>[]) 創(chuàng)建一個任務,該任務將在數(shù)組中的所有 Task<TResult> 對象完成時完成

WhenAll(IEnumerable<Task>)

創(chuàng)建一個任務,該任務將在可枚舉集合中的所有 Task 對象完成時完成。

public static System.Threading.Tasks.Task WhenAll (System.Collections.Generic.IEnumerable<System.Threading.Tasks.Task> tasks);

參數(shù)
tasks   IEnumerable<Task>
要等待完成的任務。

返回
Task
表示所有提供任務的完成的任務。

例外
ArgumentNullException
tasks 參數(shù) null。

ArgumentException
tasks 集合包含 null 任務。

注解
當對一組任務的狀態(tài)或一組任務引發(fā)的異常感興趣時,通常會調(diào)用返回 Task 對象的 WhenAll 方法的重載。

備注   對 WhenAll(IEnumerable<Task>) 方法的調(diào)用不會阻止調(diào)用線程。

如果提供的任何任務都以錯誤狀態(tài)完成,則返回的任務也將處于 Faulted 狀態(tài),其中其異常將包含每個提供的任務的未包裝異常集的聚合。

如果提供的任務均未出錯,但其中至少一個任務已取消,則返回的任務將以 Canceled 狀態(tài)結(jié)束。

如果沒有任何任務出錯且未取消任何任務,則生成的任務將以 RanToCompletion 狀態(tài)結(jié)束。

如果提供的數(shù)組/可枚舉不包含任何任務,則返回的任務將在返回給調(diào)用方之前立即轉(zhuǎn)換為 RanToCompletion 狀態(tài)。

案例

新建一個 winform 項目,建 winform 項目主要是看 Task.WhenAll 執(zhí)行過程中,是否會卡住 UI 線程,界面暫時沒添加任何控件。

代碼:

添加一個類 PingTool

using System;
using System.Net.Http;
using System.Threading.Tasks;

internal class PingTool
{
    public async Task<bool> Ping(string url)
    {
        if (string.IsNullOrEmpty(url))
            return false;
        try
        {
            using (HttpClient client = new HttpClient())
            {
                client.Timeout = TimeSpan.FromSeconds(5);
                var response = await client.GetAsync(url);
                return response.IsSuccessStatusCode;
            }
        }
        catch (System.Exception)
        {
            return false;
        }
    }
}

Form1代碼:

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WhenAllTest2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Start();
        }

        private async void Start()
        {
            List<Task<(string, bool)>> taskList = new List<Task<(string, bool)>>();
            taskList.Add(PingTest("https://www.csdn.net/"));
            taskList.Add(PingTest("https://www.zhihu.com/"));
            taskList.Add(PingTest("https://www.microsoft.com/zh-cn/"));
            taskList.Add(PingTest("https://www.baidu.com/"));
            taskList.Add(PingTest("https://github.com/"));
            var resultList = await Task.WhenAll(taskList);

            foreach (var result in resultList)
            {
                Console.WriteLine("ping {0} 的結(jié)果:{1}", result.Item1, result.Item2);
            }

            Console.WriteLine("執(zhí)行完成");
        }

        private async Task<(string, bool)> PingTest(string ip)
        {
            PingTool tool = new PingTool();
            bool result = await tool.Ping(ip);
            return (ip, result);
        }
    }
}

結(jié)果:

在執(zhí)行的過程中,拖動界面可以看到,幾乎沒有什么影響。

WhenAll(ReadOnlySpan<Task>)

創(chuàng)建一個任務,該任務將在所有提供的任務完成時完成。

public static System.Threading.Tasks.Task WhenAll (scoped ReadOnlySpan<System.Threading.Tasks.Task> tasks);

參數(shù)
tasks   ReadOnlySpan<Task>
要等待完成的任務。

返回
Task
表示所有提供任務的完成的任務。

例外
ArgumentException
tasks 數(shù)組包含 null 任務。

注解
如果提供的任何任務都以錯誤狀態(tài)完成,則返回的任務也將處于“出錯”狀態(tài),其中異常將包含每個提供任務中未包裝的異常集的聚合。

如果提供的任務均未出錯,但至少其中一個任務已取消,則返回的任務將以“已取消”狀態(tài)結(jié)束。

如果沒有任何任務出錯且未取消任何任務,則生成的任務將以 RanToCompletion 狀態(tài)結(jié)束。

如果提供的跨度不包含任何任務,則返回的任務將在返回給調(diào)用方之前立即轉(zhuǎn)換為 RanToCompletion 狀態(tài)。

在 .NET Framework  中,ReadOnlySpan 并不支持

這里我使用 .Net9 做了一個案例

代碼:

namespace WhenAllTest3
{
    internal class Program
    {
        static async Task Main(string[] args)
        {
            // 定義多個異步任務
            Task task1 = SimulateTaskAsync("任務1", 2000);
            Task task2 = SimulateTaskAsync("任務2", 1000);
            Task task3 = SimulateTaskAsync("任務3", 3000);

            // 將任務放入一個數(shù)組
            Task[] tasks = new[] { task1, task2, task3 };

            // 使用 ReadOnlySpan<Task>
            ReadOnlySpan<Task> taskSpan = new ReadOnlySpan<Task>(tasks);

            Console.WriteLine("等待所有任務完成...");

            // 等待所有任務完成
            await Task.WhenAll(taskSpan);

            Console.WriteLine("所有任務已完成。");

            Console.ReadKey();
        }

        // 模擬異步任務
        static async Task SimulateTaskAsync(string taskName, int delay)
        {
            Console.WriteLine($"{taskName} 開始執(zhí)行。");
            await Task.Delay(delay);
            Console.WriteLine($"{taskName} 執(zhí)行完成。");
        }
    }
}

運行:

WhenAll(Task[])

創(chuàng)建一個任務,該任務將在數(shù)組中的所有 Task 對象完成時完成。

public static System.Threading.Tasks.Task WhenAll (params System.Threading.Tasks.Task[] tasks);

參數(shù)
tasks  Task[]
要等待完成的任務。

返回
Task
表示所有提供任務的完成的任務。

例外
ArgumentNullException
tasks 參數(shù) null。

ArgumentException
tasks 數(shù)組包含 null 任務。

注解
當對一組任務的狀態(tài)或一組任務引發(fā)的異常感興趣時,通常會調(diào)用返回 Task 對象的 WhenAll 方法的重載。

備注   對 WhenAll(Task[]) 方法的調(diào)用不會阻止調(diào)用線程。

如果提供的任何任務都以錯誤狀態(tài)完成,則返回的任務也將處于 Faulted 狀態(tài),其中其異常將包含每個提供的任務的未包裝異常集的聚合。

如果提供的任務均未出錯,但其中至少一個任務已取消,則返回的任務將以 Canceled 狀態(tài)結(jié)束。

如果沒有任何任務出錯且未取消任何任務,則生成的任務將以 RanToCompletion 狀態(tài)結(jié)束。

如果提供的數(shù)組/可枚舉不包含任何任務,則返回的任務將在返回給調(diào)用方之前立即轉(zhuǎn)換為 RanToCompletion 狀態(tài)。

代碼:

namespace WhenAllTest3
{
    internal class Program
    {
        static async Task Main(string[] args)
        {
            Console.WriteLine("開始執(zhí)行任務...");

            // 定義多個異步任務
            Task task1 = SimulateTaskAsync("任務1", 2000);
            Task task2 = SimulateTaskAsync("任務2", 1000);
            Task task3 = SimulateTaskAsync("任務3", 3000);

            // 將任務放入一個數(shù)組
            Task[] tasks = { task1, task2, task3 };

            // 使用 Task.WhenAll 等待所有任務完成
            await Task.WhenAll(tasks);

            Console.WriteLine("所有任務已完成!");
        }

        // 模擬異步任務
        static async Task SimulateTaskAsync(string taskName, int delay)
        {
            Console.WriteLine($"{taskName} 開始執(zhí)行。");
            await Task.Delay(delay);
            Console.WriteLine($"{taskName} 執(zhí)行完成。");
        }
    }
}

運行:

WhenAll<TResult>(ReadOnlySpan<Task<TResult>>)

創(chuàng)建一個任務,該任務將在所有提供的任務完成時完成。

public static System.Threading.Tasks.Task<TResult[]> WhenAll<TResult> (scoped ReadOnlySpan<System.Threading.Tasks.Task<TResult>> tasks);

類型參數(shù)
TResult

參數(shù)
tasks  ReadOnlySpan<Task<TResult>>
要等待完成的任務。

返回
Task<TResult[]>
表示所有提供任務的完成的任務。

例外
ArgumentException
tasks 數(shù)組包含 null 任務。

注解
如果提供的任何任務都以錯誤狀態(tài)完成,則返回的任務也將處于“出錯”狀態(tài),其中異常將包含每個提供任務中未包裝的異常集的聚合。

如果提供的任務均未出錯,但至少其中一個任務已取消,則返回的任務將以“已取消”狀態(tài)結(jié)束。

如果沒有任何任務出錯且未取消任何任務,則生成的任務將以 RanToCompletion 狀態(tài)結(jié)束。 返回的任務的結(jié)果將設置為一個數(shù)組,該數(shù)組包含所提供的任務的所有結(jié)果,其順序與提供的順序相同(例如,如果輸入任務數(shù)組包含 t1、t2、t3,則輸出任務的結(jié)果將返回一個 TResult[],其中 arr[0] == t1)。Result, arr[1] == t2。結(jié)果和 arr[2] == t3。結(jié)果)。

如果提供的數(shù)組/可枚舉不包含任何任務,則返回的任務將在返回給調(diào)用方之前立即轉(zhuǎn)換為 RanToCompletion 狀態(tài)。 返回的 TResult[] 將是 0 個元素的數(shù)組。

在 .NET Framework  中,ReadOnlySpan 并不支持

代碼:

namespace WhenAllTest3
{
    internal class Program
    {
        static async Task Main(string[] args)
        {
            Console.WriteLine("開始執(zhí)行任務...");

            // 定義多個返回結(jié)果的異步任務
            Task<int> task1 = SimulateTaskAsync("任務1", 2000, 10);
            Task<int> task2 = SimulateTaskAsync("任務2", 1000, 20);
            Task<int> task3 = SimulateTaskAsync("任務3", 3000, 30);

            // 將任務放入一個數(shù)組
            Task<int>[] tasks = { task1, task2, task3 };

            // 使用 ReadOnlySpan<Task<TResult>>
            ReadOnlySpan<Task<int>> taskSpan = new ReadOnlySpan<Task<int>>(tasks);

            // 使用 Task.WhenAll 等待所有任務完成并獲取結(jié)果
            int[] results = await Task.WhenAll(taskSpan);

            Console.WriteLine("所有任務已完成,結(jié)果如下:");
            foreach (var result in results)
            {
                Console.WriteLine($"任務返回結(jié)果:{result}");
            }
        }

        // 模擬異步任務,返回一個整數(shù)結(jié)果
        static async Task<int> SimulateTaskAsync(string taskName, int delay, int result)
        {
            Console.WriteLine($"{taskName} 開始執(zhí)行,預計耗時 {delay} 毫秒...");
            await Task.Delay(delay); // 模擬異步操作
            Console.WriteLine($"{taskName} 執(zhí)行完成,結(jié)果:{result}");
            return result;
        }
    }
}

運行:

WhenAll<TResult>(IEnumerable<Task<TResult>>)

創(chuàng)建一個任務,該任務將在可枚舉集合中的所有 Task<TResult> 對象完成時完成。

public static System.Threading.Tasks.Task<TResult[]> WhenAll<TResult> (System.Collections.Generic.IEnumerable<System.Threading.Tasks.Task<TResult>> tasks);

類型參數(shù)
TResult
已完成任務的類型。

參數(shù)
tasks  IEnumerable<Task<TResult>>
要等待完成的任務。

返回
Task<TResult[]>
表示所有提供任務的完成的任務。

例外
ArgumentNullException
tasks 參數(shù) null。

ArgumentException
tasks 集合包含 null 任務。

代碼:

namespace WhenAllTest3
{
    internal class Program
    {
        static async Task Main(string[] args)
        {
            Console.WriteLine("開始執(zhí)行任務...");

            // 定義多個返回結(jié)果的異步任務
            List<Task<int>> tasks = new List<Task<int>>
            {
                SimulateTaskAsync("任務1", 2000, 10),
                SimulateTaskAsync("任務2", 1000, 20),
                SimulateTaskAsync("任務3", 3000, 30)
            };

            // 使用 Task.WhenAll 等待所有任務完成并獲取結(jié)果
            int[] results = await Task.WhenAll(tasks);

            Console.WriteLine("所有任務已完成,結(jié)果如下:");
            foreach (var result in results)
            {
                Console.WriteLine($"任務返回結(jié)果:{result}");
            }

            // 進一步處理結(jié)果
            Console.WriteLine($"任務結(jié)果總和:{results.Sum()}");
        }

        // 模擬異步任務,返回一個整數(shù)結(jié)果
        static async Task<int> SimulateTaskAsync(string taskName, int delay, int result)
        {
            Console.WriteLine($"{taskName} 開始執(zhí)行,預計耗時 {delay} 毫秒...");
            await Task.Delay(delay); // 模擬異步操作
            Console.WriteLine($"{taskName} 執(zhí)行完成,結(jié)果:{result}");
            return result;
        }
    }
}

運行:

WhenAll<TResult>(Task<TResult>[])

創(chuàng)建一個任務,該任務將在數(shù)組中的所有 Task<TResult> 對象完成時完成。

public static System.Threading.Tasks.Task<TResult[]> WhenAll<TResult> (params System.Threading.Tasks.Task<TResult>[] tasks);

類型參數(shù)
TResult
已完成任務的類型。

參數(shù)
tasks  Task<TResult>[]
要等待完成的任務。

返回
Task<TResult[]>
表示所有提供任務的完成的任務。

例外
ArgumentNullException
tasks 參數(shù) null。

ArgumentException
tasks 數(shù)組包含 null 任務。

代碼:

namespace WhenAllTest3
{
    internal class Program
    {
        static async Task Main(string[] args)
        {
            Console.WriteLine("開始執(zhí)行任務...");

            // 定義多個返回結(jié)果的異步任務
            Task<int> task1 = SimulateTaskAsync("任務1", 2000, 10);
            Task<int> task2 = SimulateTaskAsync("任務2", 1000, 20);
            Task<int> task3 = SimulateTaskAsync("任務3", 3000, 30);

            // 將任務放入數(shù)組
            Task<int>[] tasks = { task1, task2, task3 };

            // 使用 Task.WhenAll 等待所有任務完成并獲取結(jié)果
            int[] results = await Task.WhenAll(tasks);

            Console.WriteLine("所有任務已完成,結(jié)果如下:");
            foreach (var result in results)
            {
                Console.WriteLine($"任務返回結(jié)果:{result}");
            }

            // 進一步處理結(jié)果
            int sum = 0;
            foreach (var result in results)
            {
                sum += result;
            }

            Console.WriteLine($"任務結(jié)果總和:{sum}");
        }

        // 模擬異步任務,返回一個整數(shù)結(jié)果
        static async Task<int> SimulateTaskAsync(string taskName, int delay, int result)
        {
            Console.WriteLine($"{taskName} 開始執(zhí)行,預計耗時 {delay} 毫秒...");
            await Task.Delay(delay); // 模擬異步操作
            Console.WriteLine($"{taskName} 執(zhí)行完成,結(jié)果:{result}");
            return result;
        }
    }
}

結(jié)果:

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

相關(guān)文章

  • C#實現(xiàn)猜數(shù)字游戲

    C#實現(xiàn)猜數(shù)字游戲

    這篇文章主要為大家詳細介紹了C#實現(xiàn)猜數(shù)字游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • C#基礎知識之this關(guān)鍵字介紹

    C#基礎知識之this關(guān)鍵字介紹

    本文主要介紹this關(guān)鍵字的幾種使用方法,this可以代表當前實例,可以調(diào)用其他構(gòu)造函數(shù),還可以用來構(gòu)建索引器,這里都有一一舉例說明。
    2016-04-04
  • C#運用FileInfo類實現(xiàn)拷貝文件的方法

    C#運用FileInfo類實現(xiàn)拷貝文件的方法

    這篇文章主要介紹了C#運用FileInfo類實現(xiàn)拷貝文件的方法,需要的朋友可以參考下
    2014-07-07
  • unity實現(xiàn)QQ截圖功能

    unity實現(xiàn)QQ截圖功能

    這篇文章主要為大家詳細介紹了unity實現(xiàn)QQ截圖功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • C#簡單了解接口(Interface)使用方法

    C#簡單了解接口(Interface)使用方法

    這篇文章主要介紹了C#簡單了解接口(Interface)使用方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-09-09
  • C#復制數(shù)組的兩種方式及效率比較

    C#復制數(shù)組的兩種方式及效率比較

    這篇文章介紹了C#復制數(shù)組的兩種方式及效率比較,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-10-10
  • C#獲取進程和對進程的操作

    C#獲取進程和對進程的操作

    下面是一個例子:獲取進程列表、創(chuàng)建“違禁”進程名單、查找并終止進程,注意先要在項目里添加System.Management的引用
    2013-04-04
  • C#裝飾器模式(Decorator Pattern)實例教程

    C#裝飾器模式(Decorator Pattern)實例教程

    這篇文章主要介紹了C#裝飾器模式(Decorator Pattern),以一個完整實例形式講述了C#裝飾器模式的實現(xiàn)過程,有助于深入理解C#程序設計思想,需要的朋友可以參考下
    2014-09-09
  • 利用C#實現(xiàn)合并Word文檔功能

    利用C#實現(xiàn)合并Word文檔功能

    合并Word文檔可以快速地將多份編輯好的文檔合在一起,避免復制粘貼時遺漏內(nèi)容,以及耗費不必要的時間。本文將分為以下兩部分介紹如何通過C#合并Word文檔,并附上VB.NET代碼供大家參考,希望對大家有所幫助
    2022-12-12
  • C# 中的var關(guān)鍵字詳細介紹

    C# 中的var關(guān)鍵字詳細介紹

    這篇文章主要介紹了C# 中的var關(guān)鍵字詳細介紹的相關(guān)資料,需要的朋友可以參考下
    2016-12-12

最新評論

抚顺市| 南郑县| 武汉市| 板桥市| 彭泽县| 扶绥县| 宜州市| 铁岭市| 宁都县| 绥宁县| 天全县| 洪江市| 临朐县| 双城市| 图们市| 肇源县| 平顺县| 巴彦淖尔市| 海门市| 九江县| 怀仁县| 平凉市| 资兴市| 托克托县| 北辰区| 玉溪市| 铅山县| 四子王旗| 卓尼县| 夏津县| 陇川县| 阿尔山市| 洪江市| 吉木萨尔县| 阳泉市| 义马市| 科尔| 鄂伦春自治旗| 噶尔县| 麻阳| 翁源县|