Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/wordpress/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么没有一个iawaiteable和IAwaiter接口_C#_Async Await_Language Design - Fatal编程技术网

C# 为什么没有一个iawaiteable和IAwaiter接口

C# 为什么没有一个iawaiteable和IAwaiter接口,c#,async-await,language-design,C#,Async Await,Language Design,我最近了解了定制等待类型的可能性,正如问题和陈述所述,等待类型有几个要求 因此,如果一个类型T想要被等待,它必须 公开返回有效等待器的无参数方法GetAwaiter 如果a型想成为有效的等待者,它必须 实现INotifyCompletion接口 提供名为IsCompleted的布尔属性 提供返回void或TResult的无参数GetResult方法 所以现在我要问的是,如果所有这些都需要一个等待类型,为什么有些接口的这一部分不像 公共接口INotifyCompletion { 布尔已完成{get

我最近了解了定制等待类型的可能性,正如问题和陈述所述,等待类型有几个要求

因此,如果一个类型T想要被等待,它必须

公开返回有效等待器的无参数方法GetAwaiter 如果a型想成为有效的等待者,它必须

实现INotifyCompletion接口 提供名为IsCompleted的布尔属性 提供返回void或TResult的无参数GetResult方法 所以现在我要问的是,如果所有这些都需要一个等待类型,为什么有些接口的这一部分不像

公共接口INotifyCompletion { 布尔已完成{get;} 无效未完成动作继续; } 公共接口:INotifyCompletion { 无效结果; } 公共接口IAwaitable其中TAwaiter:IAwaiter { 塔吉特等待者; } 公共接口:INotifyCompletion { TResult-GetResult; } //这可能没有必要,但可能有助于确定 //返回值的可等待项 公共接口IAwaitable其中TAwaiter:IAwaiter { 塔吉特等待者; } 我也理解编译器不需要它,因为它可以在编译时检查所有这些,而不会受到任何惩罚。但是既然存在用于OnCompleted方法的接口,为什么不将用于等待和等待的接口的其余部分打包在一些接口中呢

这很可能有助于告知程序员如何实现这一点

我还知道,通过提供一个返回有效等待器的扩展方法,可以使类型成为可等待的,但同样,为什么等待器的整个接口不是打包在单个接口中,而是有漏洞,即IsCompleted属性不是任何接口的一部分,而是必需的?

如果您想使用它们,接口是可用的

请注意,它们不是强制使用的,但如果你觉得它们会让你的生活更轻松,请随意使用它们


这可能也值得一读。

我猜是因为它违反了语义。async/await是一种编译时功能,它意味着编译器应该知道在生成的状态机中使用什么类型的等待器,这在某些接口使用场景中是不可能的,这意味着在编译过程中无法确定变量的实际类型时会出现运行时多态性。因此,从本质上讲,这意味着并非所有情况都可以使用基于接口的等待程序来解决。

如果我不得不猜测,我会认为这是因为任务早在async/await之前就以TPL的形式存在。这个问题应该颠倒过来。如果所需要的只是一个GetAwaiter方法,那么为什么要添加一个接口呢?不需要。不过,这一特定细节对大多数程序员没有帮助,因为只有非常专业的代码才需要实现这一点。代码类似于Task和ValueTask中的代码。应用程序应该返回这些类型中的一种,而不是尝试实现方法也许更好的问题是,为什么要实现自己的GetAwaiter?@PanagiotisKanavos我正在寻找一种方法来实现任务的一些扩展方法,并想知道可以等待的其他类型,如ValueTask,以及如何最大限度地减少代码重复。例如,我有一个用于Task的WithTimeout扩展方法,该方法工作得非常好,但我想知道如何使此方法可供其他可等待对象(如ConfiguredTaskAwaitable)访问,这样我就可以编写Task.ConfigureAwaitfalse.WithTimeout1000这样的代码,而不必修改任何代码。是Eric Lippert的一篇博客文章,解释了为什么foreach语句使用基于模式的方法。TL;DR使用模式可以避免与接口相关的性能损失。我猜模式用于wait也是出于类似的原因。