C# 异步

C# 异步

异步和同步,可以简单理解为:

  • 同步,即大家一起走,我系个鞋带,大家等我。

  • 异步,则大家一起走,我系个鞋带,后面跟上。

而在某些场景下,是不能够大家一起走,而是需要大家先走,我后面跟上的。

static async Task Go () {
  // ...
}

等待

有些时候,我们需要进行等待操作,比如只有一个锅做菜,那么只能等待这个锅炒完菜才能炒新的菜。

await 提供了一种非阻塞方式来启动任务。

然后该任务完成后继续执行后续任务。

// 静态 异步 返回 Task 的 Main 方法
// 如果需要使用 await 则需要增加 async 修饰符
// 并且使用 Task 代替返回的类型
static async Task Main () {
  // ...
  await AsyncFn(); // 等待这个操作完成
  // ...
}

等待所有

可使用 WhenAll,它返回一个 Task,当它参数列表中的所有异步任务都完成时,返回的 Task 完成。

await Task.WhenAll(goWork, eatBreakfast, seeNew);
// 吃完早餐,看完新闻,到上班地点了,结束任务

等待任一

还有一个 WhenAny,它同样返回一个 Task, 但是与 WhenAll 不同,当它的参数列表中的任一异步任务完成时,通过返回的 Task 会知道该任务已完成。随后进行处理,并从参数列表中删除该任务。

var tasks = new List<Task> { goWork, eatBreakfast, seeNew };

while (tasks.Count > 0) {
  Task task = await Task.WhenAny(tasks);
  // todo ...
  await task;
  tasks.Remove(task); // 在 tasks 列表中移除 task
}

并发任务

很多情况下,需要同时进行多个操作,比如上班途中,可以边吃早餐,边看新闻等。

System.Threding.Tasks.Task 和相关类型是可用于推理正在进行任务的类。

使得可以编写更好的异步代码。

public async Task Main () {
  goWork();
    eatBreakfast();
  seeNew(); 
}

异步组合

异步操作后跟随同步操作的组合也是异步操作。

即,操作任意部分为异步,则整体都是异步的。

// 异步组合
public async Task Main () {
  await AsyncOperate();
    SyncOperate();
    SyncOperate();
}

异步异常

异步方法可以引发异常,并被捕获处理。

处理方式与同步方法一致。

try {
  // async operator
}
catch (AsyncErrorType e) {
  // async error handling...
}

异步场景

比如需要进行 IO 操作,使用 CPU 进行运算等。

异步编程的核心是 TaskTask<T>

它们受到 asyncawait 支持。

异步返回类型

  • Task 对于执行异步操作但并无返回值的方法。

  • Task<TResult> 对于返回值的异步方法。

  • void 对于事件处理程序。

  • 任何具有可访问的 GetAwaiter 方法的类型。该方法返回对象必须实现 System.Runtime.CompilerServices.ICriticalNotifyCompletion 接口。

  • IAsyncEnumerable<T> 对于返回异步流的方法。

  • DispatcherOperation 适用于 Windows 的异步操作。

  • IAsyncAction 适用于 UWP 中不返回值的异步操作。

  • IAsyncActionWithProgress,适用于 UWP 中只报告进程但不返回值的异步操作。

  • IAsyncOperation,适用于 UWP 中返回值的异步操作。

  • IAsyncOperationWithProgress,适用于 UWP 中既报告进程又返回值的异步操作。


C# 异步
http://localhost:8080/archives/d055cfac-d192-4ecb-86b1-ac9ee05aa7d8
作者
inksha
发布于
2024年09月14日
许可协议