在什么场景下想要使用
public async Task AsyncMethod(int num)
代替
public async void AsyncMethod(int num)
我能想到的唯一情况是您是否需要任务能够跟踪其进度。
另外,在下面的方法中,是否不需要 async 和 await 关键字?
public static async void AsyncMethod2(int num) { await Task.Factory.StartNew(() => Thread.Sleep(num)); }
通常,您会想要返回一个Task. 主要的例外应该是当您 需要 返回void类型(用于事件)时。如果没有理由不允许调用者await执行任务,为什么不允许呢?
Task
void
await
async返回的方法void在另一个方面是特殊的:它们代表 顶级异步操作 ,并且当您的任务返回异常时有额外的规则发挥作用。最简单的方法是通过一个示例来显示差异:
async
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处理程序运行。你不应该让这种情况发生。要使用您的示例,
f
g
TaskScheduler.UnobservedTaskException
是的,在这里使用async和await,它们确保您的方法在抛出异常时仍然可以正常工作。
有关详细信息,请参阅:https ://docs.microsoft.com/en-us/archive/msdn- magazine/2013/march/async-await-best-practices-in-asynchronous- programming