繁体   English   中英

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

[英]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 returnreturn 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); 
}

关于returnasync/await的故事是一样的。 对于返回类型为Task方法,您可以返回Task或使用async/await

对于Task<T>如果你使用await你必须返回T但你不能返回Task<T>因为该方法被编译到状态机,那么方法必须返回T (对于Task方法无效)

如果你不使用async/await方法将完全像其他常规方法。

当您使用await - 控制流可能会保留当前方法并返回给调用者。 假设DoSomethingAsync是一些长时间运行的操作。 你打电话给SomeMethod DoSomethingAsync任务已启动,但您不能等到它在该方法内完成 - 否则什么都不会是“异步”。 因此控制流离开Method并且应该向调用者提供返回值。 返回值是完成整个SomeMethod时完成的任务。 它可以在有或没有结果的情况下完成( TaskTask<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.

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