通常,您会想要返回一个Task
. 主要的例外应该是当您需要返回void
类型(用于事件)时。如果没有理由不允许调用者await
执行您的任务,为什么不允许它呢?
async
返回的方法void
在另一个方面是特殊的:它们代表顶级异步操作,并且当您的任务返回异常时有额外的规则发挥作用。最简单的方法是通过一个示例来显示差异:
static async void f()
{
await h();
}
static async Task g()
{
await h();
}
static async Task h()
{
throw new NotImplementedException();
}
private void button1_Click(object sender, EventArgs e)
{
f();
}
private void button2_Click(object sender, EventArgs e)
{
g();
}
private void button3_Click(object sender, EventArgs e)
{
GC.Collect();
}
f
的异常总是被“观察到”的。离开顶级异步方法的异常被简单地视为任何其他未处理的异常。g
的异常从未被观察到。当垃圾收集器来清理任务时,它看到任务导致异常,没有人处理异常。发生这种情况时,TaskScheduler.UnobservedTaskException
处理程序运行。你不应该让这种情况发生。要使用您的示例,
public static async void AsyncMethod2(int num)
{
await Task.Factory.StartNew(() => Thread.Sleep(num));
}
是的,在这里使用async
和await
,它们确保您的方法在抛出异常时仍然可以正常工作。
有关详细信息,请参阅:https ://docs.microsoft.com/en-us/archive/msdn-magazine/2013/march/async-await-best-practices-in-asynchronous-programming