[英]In async function why do I have to await?
说我有这样的方法:
private async Task SomeMethod()
{
await DoSomethingAsync();
await DoSomethingElseAsync();
return;
}
鉴于DoSomethingElseAsync
返回一个Task
,看起来你应该能够这样做:
private async Task SomeMethod()
{
await DoSomethingAsync();
return DoSomethingElseAsync();
}
但编译器抱怨这个:
由于'
SomeMethod
'是一个返回'Task
'的异步方法,因此return关键字后面不能跟一个对象表达式。 你打算退回'Task<T>
'吗?
这是为什么?
它非常类似于yield return
和return
yield return
。 对于迭代器,您可以使用这些方法中的任何一种
public IEnumerable<int> SomeIterator()
{
for(int I = 0; I < 10; I++) yield return I;
}
public IEnumerable<int> SomeIterator()
{
return Enumerable.Range(0, 10); // return result of another iterator.
}
但你不能两者兼得。 它不起作用,因为迭代器要么被编译器转换为类来处理带有yield
延迟迭代,要么就像其他返回其他东西的普通方法一样。
public IEnumerable<int> SomeIterator() // not valid
{
for(int I = 0; I < 10; I++) yield return I;
return Enumerable.Range(0, 10);
}
关于return
和async/await
的故事是一样的。 对于返回类型为Task
方法,您可以返回Task
或使用async/await
。
对于Task<T>
如果你使用await你必须返回T
但你不能返回Task<T>
因为该方法被编译到状态机,那么方法必须返回T
(对于Task
方法无效)
如果你不使用async/await
方法将完全像其他常规方法。
当您使用await
- 控制流可能会保留当前方法并返回给调用者。 假设DoSomethingAsync
是一些长时间运行的操作。 你打电话给SomeMethod
。 DoSomethingAsync
任务已启动,但您不能等到它在该方法内完成 - 否则什么都不会是“异步”。 因此控制流离开Method
并且应该向调用者提供返回值。 返回值是完成整个SomeMethod
时完成的任务。 它可以在有或没有结果的情况下完成( Task
或Task<T>
返回值)。 因此,在await
之后返回的内容不能是SomeMethod
返回类型 - 它只能是结果类型T
(如果SomeMethod
返回Task),或者只是return
指示SomeMethod
完成返回简单Task
。
在常规方法中, return
表示“从方法返回此值,如果有的话”。 在async
方法中, return
的含义更改为“将返回的Task
的结果设置为此值(如果有)”。
但是你无法将两者结合起来:在async Task
方法中,你不能直接return
一个Task
。 这样做的一个原因是,如果你await
ed,该方法实际上已经返回了一个Task
,它不能返回另一个。
在返回时, async Task
方法的行为类似于void
方法,因为它只允许return;
,但永远不会return value;
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.