TX_*_*TX_ 219 .net c# async-await .net-4.5
有没有像这样编写方法的场景:
public async Task<SomeResult> DoSomethingAsync()
{
// Some synchronous code might or might not be here... //
return await DoAnotherThingAsync();
}
Run Code Online (Sandbox Code Playgroud)
而不是这个:
public Task<SomeResult> DoSomethingAsync()
{
// Some synchronous code might or might not be here... //
return DoAnotherThingAsync();
}
Run Code Online (Sandbox Code Playgroud)
会有意义吗?
为什么return await在可以直接Task<T>从内部DoAnotherThingAsync()调用返回时使用构造?
我return await在很多地方看到代码,我想我应该错过一些东西.但据我了解,在这种情况下不使用async/await关键字并直接返回Task将在功能上等效.为什么要增加附加await层的额外开销?
svi*_*ick 172
有当一个欺骗性的情况下return在正常的方法和return await在async方法不同的行为:当与组合using(或,更一般地,任何return await在try块).
考虑这两个版本的方法:
Task<SomeResult> DoSomethingAsync()
{
using (var foo = new Foo())
{
return foo.DoAnotherThingAsync();
}
}
async Task<SomeResult> DoSomethingAsync()
{
using (var foo = new Foo())
{
return await foo.DoAnotherThingAsync();
}
}
Run Code Online (Sandbox Code Playgroud)
方法返回时,第一个方法将Dispose()是Foo对象DoAnotherThingAsync(),它可能在实际完成之前很久.这意味着第一个版本可能是错误的(因为Foo太快了),而第二个版本可以正常工作.
Ste*_*ary 85
如果您不需要async(即,您可以Task直接退货),那么请不要使用async.
在某些情况下return await,如果您要执行两个异步操作,则有用:
var intermediate = await FirstAsync();
return await SecondAwait(intermediate);
Run Code Online (Sandbox Code Playgroud)
有关async性能的更多信息,请参阅Stephen Toub 关于该主题的MSDN文章和视频.
Ser*_*rvy 23
你想要这样做的唯一原因是,如果await在早期的代码中有其他一些,或者你在返回它之前以某种方式操纵结果.可能发生的另一种方式是通过try/catch改变异常处理方式.如果你没有做任何事情,那么你是对的,没有理由增加制作方法的开销async.
And*_*ott 16
您可能需要等待结果的另一个案例是:
async Task<IFoo> GetIFooAsync()
{
return await GetFooAsync();
}
async Task<Foo> GetFooAsync()
{
var foo = await CreateFooAsync();
await foo.InitializeAsync();
return foo;
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,GetIFooAsync()必须等待结果,GetFooAsync因为T两种方法之间的类型不同,并且Task<Foo>不能直接赋值Task<IFoo>.但是,如果你等待的结果,它只是成为Foo这是直接分配给IFoo.然后异步方法只是重新打包内部Task<IFoo>和远离你的结果.
使原本简单的“ thunk”方法异步进行,则会在内存中创建一个异步状态机,而非异步状态机则不会。尽管这样做通常可以使人们指出使用非异步版本,因为它效率更高(的确如此),这也意味着在挂起的情况下,您没有证据表明该方法已包含在“返回/继续堆栈”中这有时会使理解挂起变得更加困难。
所以是的,当性能不是很关键(通常不是)时,我将对所有这些重击方法都进行异步处理,以便我拥有异步状态机来帮助我以后诊断挂起,并帮助确保是否重击方法随着时间的推移而发展,他们将确保返回错误的任务,而不是抛出错误。
这也让我感到困惑,我觉得之前的答案忽略了您的实际问题:
当您可以直接从内部 DoAnotherThingAsync() 调用返回 Task 时,为什么要使用 return await 构造?
好吧,有时您实际上想要的是Task<SomeType>,但大多数时候您实际上想要的是 的实例SomeType,即任务的结果。
从您的代码:
async Task<SomeResult> DoSomethingAsync()
{
using (var foo = new Foo())
{
return await foo.DoAnotherThingAsync();
}
}
Run Code Online (Sandbox Code Playgroud)
不熟悉语法的人(例如我)可能认为这个方法应该返回 a Task<SomeResult>,但由于它被标记为async,这意味着它的实际返回类型是SomeResult。如果您只是使用return foo.DoAnotherThingAsync(),您将返回一个无法编译的任务。正确的方法是返回任务的结果,所以return await.
如果不使用return wait,则可能在调试时或在异常日志中打印堆栈跟踪时破坏堆栈跟踪。
当您返回任务时,该方法已实现其目的,并且不在调用堆栈中。使用时return await,将其保留在调用堆栈中。
例如:
使用await时调用堆栈:A从B等待任务=> B从C等待任务
不使用等待时调用堆栈:A正在等待C返回的B任务。
| 归档时间: |
|
| 查看次数: |
33199 次 |
| 最近记录: |