[英]Is it possible to have C# async method return type to be something not Task<T> or 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>
,Task
和void
。
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)仅支持Task
, Task<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>
, Task
和void
作为有效的返回类型。 根据C#语言规范 ,声明如下:
10.15异步功能
异步方法的返回类型必须是void或任务类型。
随着UWP的推出,您还可以获得四种内置类型:
IAsyncAction
IAsyncActionWithProgress<TProgress>
IAsyncOperation<TResult>
IAsyncOperationWithProgress<TResult, TProgress>
这些被认为是“异步类型”,您可以按照预期使用async
和await
关键字。
更多来自规范:
异步方法的返回类型必须是void或任务类型 。 任务类型是
System.Threading.Tasks.Task
和从System.Threading.Tasks.Task<T>
构造的类型。 为简洁起见,在本章中,这些类型分别称为Task
和Task<T>
。 返回任务类型的异步方法被称为任务返回。任务类型的确切定义是实现定义的,但从语言的角度来看,任务类型处于不完整,成功或出现故障的状态之一。 出现故障的任务会记录相关的异常。 成功的
Task<T>
记录类型T
的结果。 任务类型是等待的,因此可以是等待表达式的操作数
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.