繁体   English   中英

如果可以编写我们自己的等待,那么为什么异步方法只能返回Task <T>,Task和void?

[英]If it's possible to write our own awaitables, then why can async methods only return Task<T>, Task and void?

我正在查看MSDN文档,它说

异步方法有三种可能的返回类型: Task<TResult>Taskvoid

https://msdn.microsoft.com/en-us/library/mt674893.aspx

但是,我记得在其他地方读到可以写作await自定义await者。 我怎样才能调和这两个事实呢?

await支持任何类型的“等待”,它们是遵循特定模式的对象实例( GetAwaiter等)。

async生成一个状态机,它只知道如何创建Task / Task<T> awaitables(或返回void )。

因此,您可以创建自己的自定义等待对象并返回该对象,但您必须明确地执行此操作。 您不能使用async来执行此操作。

编译器团队目前正在考虑async添加ValueTask支持 这将允许您使用遵循模式的“异步方法构建器”。 然后你就可以使用async以及await操作任何类型的“任务”类型。 不幸的是,它仍然不允许async方法返回接口类型,但是语言的其他部分的更改是必要的。

.NET附带的本机类(特别是TaskAwaiter)仅支持TaskTask<T>void等待,因此这是MSDN告诉您的所有内容。 但是,您可以编写允许等待其他类型的自定义等待者。

根据https://weblogs.asp.net/dixin/understanding-c-sharp-async-await-2-awaitable-awaiter-pattern ,在以下情况下,对象是等待的:

  • 它有一个GetAwaiter()方法(实例方法或扩展方法);
  • 它的GetAwaiter()方法返回一个awaiter。 在下列情况下,对象是等待者:
    • 它实现了INotifyCompletion或ICriticalNotifyCompletion接口;
    • 它有一个IsCompleted,它有一个getter并返回一个布尔值;
    • 它有一个GetResult()方法,它返回void或结果。

您提供的链接的第一行内容如下:

更新日期:2015年7月20日

所以这有点过时了。 话虽如此,最初的async方法只有Task<TResult>Taskvoid作为有效的返回类型。 根据C#语言规范 ,声明如下:

10.15异步功能

异步方法的返回类型必须是void或任务类型。

随着UWP的推出,您还可以获得四种内置类型:

  1. IAsyncAction
  2. IAsyncActionWithProgress<TProgress>
  3. IAsyncOperation<TResult>
  4. IAsyncOperationWithProgress<TResult, TProgress>

这些被认为是“异步类型”,您可以按照预期使用asyncawait关键字。

更多来自规范:

异步方法的返回类型必须是void或任务类型 任务类型是System.Threading.Tasks.Task和从System.Threading.Tasks.Task<T>构造的类型。 为简洁起见,在本章中,这些类型分别称为TaskTask<T> 返回任务类型的异步方法被称为任务返回。

任务类型的确切定义是实现定义的,但从语言的角度来看,任务类型处于不完整,成功或出现故障的状态之一。 出现故障的任务会记录相关的异常。 成功的Task<T>记录类型T的结果。 任务类型是等待的,因此可以是等待表达式的操作数

暂无
暂无

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

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