同步与异步:.NET 中的 Task.WaitAll 和 Task.WhenAll

在 C# 中,异步编程通常涉及同时运行多个任务。处理多个任务的两种常见方法是 Task.WaitAll 和 Task.WhenAll。虽然它们看起来很相似,但它们的用途不同,并且用于不同的场景。本文探讨了 Task.WaitAll 和 Task.WhenAll 之间的区别,并通过实际示例来说明它们的用法。

什么是 Task.WaitAll?

Task.WaitAll 是一种同步方法,它会阻塞调用线程,直到所有提供的任务都已完成。当您需要确保一组任务在继续之前已完成时,该方法很有用,但它以阻塞方式执行,这意味着调用 Task.WaitAll 的线程会被占用,直到所有任务都完成为止。

Task.WaitAll 的示例用法

复制代码
using System;
using System.Threading.Tasks;
class Program
{
    static void Main()
    {
        Task task1 = Task.Run(() => PerformTask(1));
        Task task2 = Task.Run(() => PerformTask(2));
        Task task3 = Task.Run(() => PerformTask(3));
        Task.WaitAll(task1, task2, task3); // Blocks until all tasks complete
        Console.WriteLine("All tasks completed.");
    }
    static void PerformTask(int taskId)
    {
        Console.WriteLine($"Task {taskId} starting.");
        Task.Delay(1000).Wait(); // Simulate work
        Console.WriteLine($"Task {taskId} completed.");
    }
}

在此示例中,Task.WaitAll 阻止主线程,直到所有三个任务都完成。

什么是 Task.WhenAll?

Task.WhenAll 是一种异步方法,当所有提供的任务都完成后,该方法将返回单个任务。与 Task.WaitAll 不同,它不会阻止调用线程。相反,它允许调用代码继续异步执行。

Task.WhenAll 的示例用法

复制代码
using System;
using System.Threading.Tasks;
class Program
{
    static async Task Main()
    {
        Task task1 = Task.Run(() => PerformTask(1));
        Task task2 = Task.Run(() => PerformTask(2));
        Task task3 = Task.Run(() => PerformTask(3));
        await Task.WhenAll(task1, task2, task3); // Waits for all tasks to complete asynchronously
        Console.WriteLine("All tasks completed.");
    }
    static void PerformTask(int taskId)
    {
        Console.WriteLine($"Task {taskId} starting.");
        Task.Delay(1000).Wait(); // Simulate work
        Console.WriteLine($"Task {taskId} completed.");
    }
}

在此示例中,Task.WhenAll 允许主方法等待所有任务的完成,而不会阻塞调用线程。

主要区别

阻塞与非阻塞

  1. 阻塞与非阻塞
  • Task.WaitAll:阻止调用线程,直到所有任务完成。
  • Task.WhenAll:返回一个可以等待的任务,允许调用线程继续异步执行。
  1. 返回类型
  • Task.WaitAll:没有返回值。
  • Task.WhenAll:返回代表所有提供的任务完成的 Task。
  1. 应用场景
  • Task.WaitAll:当您需要阻止直到任务完成时使用,通常在非 UI 或控制台应用程序中。
  • Task.WhenAll:用于异步编程,尤其是在不希望阻塞主线程的 UI 应用程序中。

实际用例

  1. 何时使用 Task.WaitAll
  • 在控制台应用程序中,您需要确保某些任务在继续之前已经完成。
  • 当您处理不支持异步/等待模式的遗留代码时。
  1. 何时使用 Task.WhenAll
  • 在 UI 应用程序中保持界面响应。
  • 在 Web 应用程序中处理多个异步操作而不阻塞主线程。

结论

Task.WaitAll 和 Task.WhenAll 是 C# 中处理多个任务的必备工具。当您需要阻止调用线程直到任务完成时,请使用 Task.WaitAll;当需要异步等待时,请使用 Task.WhenAll。了解它们的区别和适当的用例可以帮助您编写更高效、响应更快的应用程序。

相关推荐
samble6 小时前
从零搭建灌装监控系统(十七):LiveCharts 实时温度曲线
c#·wpf·mvvm·modbus·工业控制
淡海水15 小时前
02-07-原理篇-GC暂停时间的本质
开发语言·unity·c#·gc·暂停时间
小羊没烦恼!16 小时前
OS X 上使用.NET开发应用程序
开发语言·前端·数据库·人工智能·c#·策略模式
Behavior18 小时前
Unity 7.0 Alpha 拆解:编辑器干掉 Mono 换 CoreCLR
c#·unity3d·游戏开发
淡海水18 小时前
02-06-原理篇-增量式GC与并发GC
算法·unity·c#·并发·gc·增量
Vertira19 小时前
C# 函数封装成 DLL,
开发语言·c#
浅尝辄止;20 小时前
设计模式在HIS/LIS医疗系统中的完整实践指南(C#版)
开发语言·设计模式·c#
kimloner1 天前
开源一个 376KB 的 Windows 桌面小工具:便签 + 截图标注 + OCR + 待办提醒(C# / WinForms)
windows·开源·c#·ocr·winforms
阿松爱学习1 天前
【Unity开发】Aspose.PDF的使用
unity·pdf·c#
半亩码田1 天前
C#转Python第4.8篇:正则表达式:Python re 模块 vs C# System.Text.RegularExpressions
python·正则表达式·c#