C# Task异步的常用方法

Task异步的常用方法

C# 中的 Task 类是 System.Threading.Tasks 命名空间的一部分,用于表示异步操作。

一、Task.Run(Action action):

此静态方法用于在后台运行一个新任务,并返回与该任务关联的 Task 实例。

  1. 本质是将任务放入线程池执行,自动启动,适合CPU 密集型或简单异步操作
  2. 注意:返回的 Task 无法手动控制启动(已自动启动)。
cs 复制代码
Task.Run(() => Console.WriteLine("后台执行"));

二、Task.Start():

用于手动启动通过 new Task(...) 创建的未启动任务 (默认状态为 Created)。

cs 复制代码
var task = new Task(() => Console.WriteLine("手动启动"));
task.Start(); // 必须调用才会执行

三、Task.Delay(int millisecondsDelay):

此静态方法创建一个在指定延迟之后完成的 Task。这对于定时操作或模拟长时间运行的任务非常有用。

cs 复制代码
await Task.Delay(1000); // 等待1秒

四、任务等待相关方法(阻塞 vs 非阻塞)

方法 特性 适用场景
await Task.WhenAll 非阻塞等待所有任务完成 异步方法中,需要等待多个任务全部完成后再继续
await Task.WhenAny 非阻塞等待任一任务完成 异步方法中,只需等待最快完成的任务结果
Task.WaitAll 阻塞当前线程等待所有任务 同步方法中强制等待(不推荐在异步代码中使用)
Task.WaitAny 阻塞当前线程等待任一任务 同步方法中需立即响应第一个完成的任务
Task.Wait() 阻塞当前线程等待单个任务 同步方法中等待单个任务(等价于 WaitAll 单任务)

关键区别

  1. await 搭配 WhenAll/WhenAny非阻塞等待,会释放当前线程,适合异步上下文(如 UI 线程),避免界面卡顿。
  2. Wait()/WaitAll()/WaitAny()阻塞等待 ,会冻结当前线程,可能导致性能问题(如 UI 无响应),仅建议在纯同步代码中使用。

1.Task.WhenAll(Task\[\] tasks):

注意:由于此调用不会默认等待,需要再前面添加await。

cs 复制代码
var task1 = Task.Run(() => { /* 任务1 */ });
var task2 = Task.Run(() => { /* 任务2 */ });
 
await Task.WhenAll(task1, task2);

2.Task.WhenAny(Task\[\] tasks):

注意:由于此调用不会默认等待,需要再前面添加await。

cs 复制代码
var task1 = Task.Run(() => { /* 任务1 */ });
var task2 = Task.Run(() => { /* 任务2 */ });
 
var completedTask = await Task.WhenAny(task1, task2);

3.Task.Wait():

cs 复制代码
var task = Task.Run(() => { /* 代码 */ });
task.Wait();

4.Task.WaitAll(Params Task\[\])

cs 复制代码
var task1 = Task.Run(() => { /* 任务1 */ });
var task2 = Task.Run(() => { /* 任务2 */ });
 
var completedTask = Task.WaitAll(task1, task2);

5.Task.WaitAny(Params Task\[\])

cs 复制代码
var task1 = Task.Run(() => { /* 任务1 */ });
var task2 = Task.Run(() => { /* 任务2 */ });
 
var completedTask = Task.WaitAny(task1, task2);

五、Task.ContinueWith(Action continuationAction):

此方法用于在当前任务完成后执行另一个操作。这对于链式(嵌套)任务执行非常有用。(等待一个任务完成)

cs 复制代码
// 正常情况下 t1 和 t2 不知道谁先执行完
Task<string> t1 = new Task<string>(F1);
Task<string> t2 = new Task<string>(F2);
Task<string> t3 = new Task<string>(F3);
 
//t1先执行 t2后执行 
t1.ContinueWith(t =>
{
    // t1执行完之后 再去执行
    t2.Start(); //第二任务
    t2.ContinueWith(t4 =>
    {
        //第二个任务完成了
        //第三个任务对象
        t3.Start();
        t3.ContinueWith(t5 =>
        {
            Console.WriteLine("保证第三个任务完成");
        });
    });
});

注意:在使用 Task 类时,应始终考虑处理异常和取消操作。这可以通过使用 try-catch 语句和 CancellationToken 来实现。

相关推荐
北域码匠10 小时前
PID 控制算法完整详解(C# 原生实现,无第三方库)
c#·pid控制·工控开发·闭环控制·自动控制算法·数字pid·增量式pid
离陌在学C#11 小时前
C# 重载与重写:深入理解面向对象编程的核心概念
java·c#
asdzx6714 小时前
Java 实战:基于 Spire.Doc 高效提取 Word 文档文本与图片
java·c#·word
小金子会发光14 小时前
C# WinForms 基于 Socket 手搓 Modbus TCP 调试助手(支持 01/02/03/04/05/06/0F/10)
c#·socket·plc·modbus tcp·工业通信
慧都小妮子16 小时前
PDF图片提取总“褪色“?Aspose.PDF 多层级提取能力详解
pdf·c#·.net·图片处理·文档处理·色彩空间
-银雾鸢尾-18 小时前
C#中的反射关键类-Type
开发语言·c#
淡海水19 小时前
15-07-YooAsset面试篇-Unity性能优化与内存管理
java·unity·面试·性能优化·c#·游戏引擎
离陌在学C#20 小时前
C# 多态:面向对象编程的核心特性详解
开发语言·c#
一念春风20 小时前
文件透明加密(C、C#)
c语言·c#·wpf
hez20101 天前
.NET 11 Runtime Async 详解
c#·.net·.net core