简体   繁体   English

在异步功能中我为什么要等待?

[英]In async function why do I have to await?

Say I have method such as this: 说我有这样的方法:

private async Task SomeMethod()
{
  await DoSomethingAsync();
  await DoSomethingElseAsync();
  return;
}

Given that DoSomethingElseAsync returns a Task it would seem like you should be able to do this: 鉴于DoSomethingElseAsync返回一个Task ,看起来你应该能够这样做:

private async Task SomeMethod()
{
  await DoSomethingAsync();
  return DoSomethingElseAsync();
}

but the compiler complains about this: 但编译器抱怨这个:

Since ' SomeMethod ' is an async method that returns ' Task ', a return keyword must not be followed by an object expression. 由于' SomeMethod '是一个返回' Task '的异步方法,因此return关键字后面不能跟一个对象表达式。 Did you intend to return ' Task<T> '? 你打算退回' Task<T> '吗?

Why is that? 这是为什么?

Its pretty much like how yield return and return works. 它非常类似于yield returnreturn yield return for an iterator you have either of these methods 对于迭代器,您可以使用这些方法中的任何一种

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.
}

but you cant have both. 但你不能两者兼得。 it doesn't work, because an iterator is either converted to a class by compiler to handle lazy iteration with yield , or its just like other normal methods that returns something else. 它不起作用,因为迭代器要么被编译器转换为类来处理带有yield延迟迭代,要么就像其他返回其他东西的普通方法一样。

public IEnumerable<int> SomeIterator() // not valid
{
    for(int I = 0; I < 10; I++) yield return I;
    return Enumerable.Range(0, 10); 
}

The story is same about return and async/await . 关于returnasync/await的故事是一样的。 for method that has return type of Task you either return Task or use async/await . 对于返回类型为Task方法,您可以返回Task或使用async/await

for Task<T> if you use await you must return T but you can not return Task<T> because the method is compiled into state machine, then method must return T . 对于Task<T>如果你使用await你必须返回T但你不能返回Task<T>因为该方法被编译到状态机,那么方法必须返回T (for Task method is void) (对于Task方法无效)

if you don't use async/await method will be exactly like other normal methods. 如果你不使用async/await方法将完全像其他常规方法。

When you use await - control flow might leave current method and return back to the caller. 当您使用await - 控制流可能会保留当前方法并返回给调用者。 Suppose DoSomethingAsync is some long running operation. 假设DoSomethingAsync是一些长时间运行的操作。 You call SomeMethod . 你打电话给SomeMethod DoSomethingAsync task is started but then you cannot wait for it to complete inside that method - otherwise nothing will be "async". DoSomethingAsync任务已启动,但您不能等到它在该方法内完成 - 否则什么都不会是“异步”。 So control flow leaves Method and should provide a return value to the caller. 因此控制流离开Method并且应该向调用者提供返回值。 Return value is a task which completes when whole SomeMethod is completed. 返回值是完成整个SomeMethod时完成的任务。 It can complete with or without result ( Task or Task<T> return value). 它可以在有或没有结果的情况下完成( TaskTask<T>返回值)。 For that reason what you return after await could not be return type of SomeMethod - it can only be result type T (if SomeMethod returns Task) or just simple return to indicate completion of SomeMethod if it returns simple Task . 因此,在await之后返回的内容不能是SomeMethod返回类型 - 它只能是结果类型T (如果SomeMethod返回Task),或者只是return指示SomeMethod完成返回简单Task

In a normal method, return means "return this value, if any, from the method". 在常规方法中, return表示“从方法返回此值,如果有的话”。 In an async method, the meaning of return is changed to "set the result of the returned Task to this value, if any". async方法中, return的含义更改为“将返回的Task的结果设置为此值(如果有)”。

But you can't combine the two: in an async Task method, you can't directly return a Task . 但是你无法将两者结合起来:在async Task方法中,你不能直接return一个Task One reason for this is that if you await ed, the method actually already returned a Task and it can't return another one. 这样做的一个原因是,如果你await ed,该方法实际上已经返回了一个Task ,它不能返回另一个。

When it comes to returning, async Task method behaves like a void method, in that it only allows return; 在返回时, async Task方法的行为类似于void方法,因为它只允许return; , but never return value; ,但永远不会return value; .

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM