C# 何时使用异步返回任务
当谈到处理异步/任务时方法应该是什么样子时,我有点困惑 根据我的理解,仅仅创建一个新任务的方法不需要是异步的,因为这会产生开销,因为它会在一个新任务中封装漏洞 因此:C# 何时使用异步返回任务,c#,.net,task-parallel-library,async-await,C#,.net,Task Parallel Library,Async Await,当谈到处理异步/任务时方法应该是什么样子时,我有点困惑 根据我的理解,仅仅创建一个新任务的方法不需要是异步的,因为这会产生开销,因为它会在一个新任务中封装漏洞 因此: async Task _doStuff() { await Task.Run(()=> _stuff()); } 这样比较好: Task _doStuff() { return Task.Run(()=> _stuff()); } 然而,如果有一些先决条件检查,它会变得更复杂一些 那哪条路更好 as
async Task _doStuff()
{
await Task.Run(()=> _stuff());
}
这样比较好:
Task _doStuff()
{
return Task.Run(()=> _stuff());
}
然而,如果有一些先决条件检查,它会变得更复杂一些
那哪条路更好
async Task _doStuff()
{
if(stuffWasDone)
return;
await Task.Run(()=> _stuff());
}
或
您不必使用Task.Run来生成任务。任务就是承诺。
如果任务不需要执行,不要创建任务。使用Task.Run会有在线程池线程上调用空lambda的开销,您不需要这样做。只要返回就足够了
如果实际不需要任何任务,也可以使用Task.FromResult:
Task DoStuffAsync()
{
if(stuffWasDone)
{
return Task.FromResult(0);
}
return Task.Run(() => _stuff());
}
如果不想重新生成任务,只需将其放入局部变量:
private static Task _emptyTask = Task.FromResult(0);
至于你的第一个wait vs return wait的例子,你不能说一个比另一个更好,因为它们有不同的用途。前者将异步等待任务完成后再返回,而后者将向调用者返回热任务。这对于异常处理很重要。更重要的是,如果您以后不打算使用任务的结果,那么使用wait将导致状态机的冗余生成
另一方面。让最终用户显式调用Task.Run,而不要用异步行为愚弄他们。您不必使用Task.Run来生成任务。任务就是承诺。
如果任务不需要执行,不要创建任务。使用Task.Run会有在线程池线程上调用空lambda的开销,您不需要这样做。只要返回就足够了
如果实际不需要任何任务,也可以使用Task.FromResult:
Task DoStuffAsync()
{
if(stuffWasDone)
{
return Task.FromResult(0);
}
return Task.Run(() => _stuff());
}
如果不想重新生成任务,只需将其放入局部变量:
private static Task _emptyTask = Task.FromResult(0);
至于你的第一个wait vs return wait的例子,你不能说一个比另一个更好,因为它们有不同的用途。前者将异步等待任务完成后再返回,而后者将向调用者返回热任务。这对于异常处理很重要。更重要的是,如果您以后不打算使用任务的结果,那么使用wait将导致状态机的冗余生成
另一方面。让最终用户显式调用Task.Run,而不要用异步行为愚弄他们。@CSharpie简单返回不起作用是什么意思?Task.FromResult不是一个简单的返回语句。@PatrickHofman您永远不应该从返回任务的方法返回null。相反,返回已完成的任务、有故障的任务、已取消的任务或只是抛出异常。但请记住不能为空。@SriramSakthivel:您能解释一下原因吗?@patrickhoffman因为任务是一个承诺,它与调用代码起着契约的作用。返回null的任务是意外行为。纵观BCL异步API,您总是会得到某种形式的任务,它描述了任务内部发生的行为。null将使调用方感到意外,并在大多数情况下导致未定义的行为。@patrickhoffman,因为谁关心检查null以查找方法返回的任务?您不能等待,否则将抛出NRE,或者调用Wait也将导致NRE。NRE没有提供关于什么是空的信息。使调试变得更糟。@CSharpie简单返回不起作用是什么意思?Task.FromResult不是一个简单的返回语句。@PatrickHofman您永远不应该从返回任务的方法返回null。相反,返回已完成的任务、有故障的任务、已取消的任务或只是抛出异常。但请记住不能为空。@SriramSakthivel:您能解释一下原因吗?@patrickhoffman因为任务是一个承诺,它与调用代码起着契约的作用。返回null的任务是意外行为。纵观BCL异步API,您总是会得到某种形式的任务,它描述了任务内部发生的行为。null将使调用方感到意外,并在大多数情况下导致未定义的行为。@patrickhoffman,因为谁关心检查null以查找方法返回的任务?您不能等待,否则将抛出NRE,或者调用Wait也将导致NRE。NRE没有提供关于什么是空的信息。使调试变得更糟。