使用 async/await/TPL 的这两个函数有什么区别?

What is the difference between these two functions using async/await/TPL?

我想我今天已经成功地迷惑了自己。

public void DoSomething1()
{
    Task.Delay(1000);
}

public async void DoSomething2()
{
    await Task.Delay(1000);
}

这两个函数在调用时内部发生的事情有什么区别?使用不 return 和 Taskasync 方法的目的是什么?

What is the difference between these two functions in terms of what happens within them when they are called?

DoSomething1是一种同步方法。因此:

  • 它开始一个异步延迟然后忽略它
  • 任何来自异步延迟的异常都会被静默忽略。
  • 来自 DoSomething 的任何异常都会直接引发给调用者。

DoSomething2 是一个异步的 void 方法。因此:

  • 它开始一个异步延迟然后观察它
  • 异步延迟的任何异常是 re-raised 在 SynchronizationContext 上,在 DoSomething2 开始执行时是当前的。这通常会导致程序终止。
  • 来自 DoSomething2 的任何异常也会在 SynchronizationContext 上引发,结果相同。

What is the purpose of using an async method that does not return a Task?

async void不是天生的东西。例如,F# 中根本不存在等效项。 async void 已添加到 C#/VB 以使事件处理程序变为异步,而无需更改整个事件处理或委托系统。

简而言之,您应该避免 async void,并且只将它们用于事件处理程序(或事件处理程序的逻辑等价物,如 MVVM 中的 ICommand.Execute)。