[英]When to return task over using async
对于处理异步/任务时的方法外观,我有些困惑。
根据我的理解,只需要创建一个新任务的方法就不需要异步,因为这会产生开销,因为它会将漏洞包裹在新任务中。
所以这:
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
具有在线程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
,不要用异步行为来欺骗他们。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.