何时使用异步返回任务
本文关键字:任务 返回 异步 何时使 | 更新日期: 2023-09-27 18:34:51
当谈到处理异步/任务时,方法应该是什么样子时,我感到有些困惑。
根据我的理解,仅创建新任务的方法不需要异步,因为这会产生开销,因为它将孔包裹在新任务中。
所以这个:
async Task _doStuff()
{
await Task.Run(()=> _stuff());
}
这样更好:
Task _doStuff()
{
return Task.Run(()=> _stuff());
}
但是,如果有一些先决条件检查,它会变得有点复杂那么哪种方式更好呢?
async Task _doStuff()
{
if(stuffWasDone)
return;
await Task.Run(()=> _stuff());
}
或
Task _doStuff()
{
if(stuffWasDone)
return Task.Run(()=> {}); // this could be a static-readonly in some helper like AsyncHelper.Empty(); as there is no FromResult for Task.
return Task.Run(()=> _stuff());
}
您不必使用 Task.Run
即可生成Task
。Task
就是承诺。如果不需要执行Task
,请不要创建。使用 Task.Run
具有在线程池线程上调用空 lambda 的开销,您不需要它。只需返回就足够了。
如果实际上不需要Task
,您也可以使用 Task.FromResult
:
Task DoStuffAsync()
{
if(stuffWasDone)
{
return Task.FromResult(0);
}
return Task.Run(() => _stuff());
}
如果您不想重新生成Task
,只需将其放在局部变量中:
private static Task _emptyTask = Task.FromResult(0);
至于你的第一个例子 await
vs return await
,你不能说一个比另一个"更好",因为它们有不同的目的。前者将异步等待Task
完成,然后再返回,而后者将向调用方返回热任务。这在异常处理方面很重要。更重要的是,如果您之后不打算使用任务的结果,则使用 await
将导致冗余生成状态机。
另一方面,在异步包装器中包装同步方法是一种不好的做法。让最终用户显式调用Task.Run
,不要用异步行为欺骗他们。