在异步函数中,为什么我必须等待?
说我有方法,像这样:在异步函数中,为什么我必须等待?
private async Task SomeMethod()
{
await DoSomethingAsync();
await DoSomethingElseAsync();
return;
}
鉴于DoSomethingElseAsync
返回Task
它似乎像你应该能够做到这一点:
private async Task SomeMethod()
{
await DoSomethingAsync();
return DoSomethingElseAsync();
}
但编译器抱怨这一点:
由于'
SomeMethod
'是返回'Task
'的异步方法,因此返回关键字不得后面跟着一个对象表达式。你打算返回'Task<T>
'吗?
这是为什么?
它很像yield return
和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>
,如果你使用等待你必须返回T
但由于该方法被编译成状态机将无法返回Task<T>
,则方法必须返回T
。 (对于Task
方法无效)
如果您不使用async/await
方法将与其他常规方法完全相同。
这与Evk的评论结合起来很有意义。 虽然我仍然觉得有点dissapointing'等待Thing1();等待Thing2();返回'和'等待Thing1();返回Thing2();'不要简单地编译成相同的代码,因为它仍然是合乎逻辑的(至少在我的脑海里!) – DJL
你应该这样做
private async Task<SomeReturnType> SomeMethod()
{
return await DoSomethingElseAsync();
}
或者你可以做
private async Task<SomeReturnType> SomeMethod()
{
SomeReturnType someResult = await DoSomethingAsync();
return someResult;
}
您需要指定其键入您的任务回报。 而你必须等待异步任务。
这就是OP的尝试,并没有工作 –
也许尝试返回一个任务
请阅读问题和错误信息。你不能*从异步**方法**返回任何东西**。 '异步任务'是一种方法,而不是一种功能。 –
当您使用await
- 控制流可能会离开当前的方法并返回给调用者。假设DoSomethingAsync
是一些长时间运行的操作。您致电SomeMethod
。 DoSomethingAsync
任务已启动,但您不能等待它在该方法内完成 - 否则没有任何内容会成为“异步”。所以控制流程离开Method
并且应该向呼叫者提供返回值。返回值是在完成整个SomeMethod
时完成的任务。它可以完成有或没有结果(Task
或Task<T>
返回值)。出于这个原因,你await
后返回的内容不能是SomeMethod
返回类型 - 它只能是结果型T
(如果SomeMethod
返回的任务),或者只是简单的return
指示的SomeMethod
完成,如果返回简单Task
。
在通常的方法中,return
的意思是“从方法中返回该值,如果有的话”。在async
方法中,return
的含义更改为“将返回的Task
的结果设置为该值(如果有)”。
但你不能将二者结合起来:在async Task
方法,你不能直接return
一个Task
。其中一个原因是,如果您使用await
版本,则该方法实际上已经返回Task
,并且无法返回另一个。
当谈到回国,async Task
方法的行为就像一个void
方法,因为它仅允许return;
,但从来没有return value;
。
@YvetteColomb它不是* this *问题的确切副本。 OP不询问何时使用await。这问''为什么我不能返回任务?' –
@YvetteColomb这不是重复的,你所指的问题是什么时候使用await,这个问是为什么第二个方法不能简单地返回而不是写await,我认为英语非常明确地认定这两者是不同的。 –
在第一个'await DoSomethingAsync();'完成之前 - 方法已经返回给调用者(毕竟它是异步方法)。所以在'await'之后你无法返回特定的值 - 调用者此时已经收到一个返回值并向前移动。 – Evk