当前位置: 首页 > 知识库问答 >
问题:

C# 5.0 异步中的可等待和等待者

申屠亦
2023-03-14

任务或任务

我们也可以定义自己的可实现对象。对象应具有以下资格。

    < li >它有一个GetAwaiter()方法(实例方法或扩展方法); < li >其GetAwaiter()方法返回一个Awaiter。在下列情况下,对象是一个标识符: < ul > < li >它实现INotifyCompletion或ICriticalNotifyCompletion接口; < li >它有一个IsCompleted,它有一个getter并返回一个Boolean < li >它有一个GetResult()方法,该方法返回void或一个结果。

我的问题是,为什么微软不提供一个接口来约束这些可用的对象?当前实现可应用对象的方法有点复杂。

共有3个答案

郜昊苍
2023-03-14

我认为主要原因是您在第 #1 点中所说的

实例方法或扩展方法

简单地说,因为他们希望通过为对象定义扩展方法使用户能够使对象可等待,因此,即使您不拥有对象,也可以使对象可等待。

查看这篇文章

司寇飞航
2023-03-14

这与他们对foreach关键字所做的操作一致(请参阅C#语言规范“foreach语句”的8.8.4节)。

基本上就是鸭式打字;如果该类型实现了一个< code>MoveNext方法和一个< code>Current属性,C#编译器只需知道如何循环访问由对象公开的序列。

这也适用于集合初始化器(参见C#语言规范“集合初始化器”的第7.6.10.3节);唯一的要求是该类型实现了System.Collections.IE可编号接口并具有Add方法。

也就是说,await 关键字只是遵循先前的先例,不需要特定的接口实现(尽管如果您选择使用它们,接口会提供这些方法),只是编译器可以识别的方法模式。

西门梓
2023-03-14

Lucian Wischik的博客文章为什么异步方法必须返回Task?

总而言之(我没有公正地写博文,你应该阅读它),问题是任务已经存在,所以引入接口意味着

  • 所有内部方法都需要更改为接口,这是一个中断性更改,因此框架人们几乎不可能愿意这样做。
  • 作为一名程序员,你需要不断地决定是要返回任务还是接口,这个决定并不重要。
  • 编译器始终需要一个具体类型,因此即使您从方法返回接口,它仍将编译为 Task

来自上面的影响是如此巨大,以至于提供一个接口是没有意义的。

 类似资料:
  • 我正在尝试将数据库调用移出控制器,以清理并使其可测试。当它们在控制器中时,一切都会顺利进行。我将它们移出控制器,并添加了一个异步,以确保我们等待。否则,我将调用的中的函数。现在,一旦我使用async/await,控制器中的函数就会认为没有用户,因为它没有等待。 有几个关于异步等待的SO问题,但我没有找到一个解决我的问题。我确实验证了返回了我的用户,并添加了控制台日志来显示路径。 节点猫鼬异步等待似

  • 我试图在react/electron项目中使用async/await,但它不起作用。我想要的是获取docker容器状态列表。但是安慰。日志(列表)返回未定义的。 有人能帮我吗?:)

  • 问题内容: 我是一名普通的C#开发人员,但有时我会使用Java开发应用程序。我想知道是否有Java等效于C#async / await?简单来说,java相当于什么: 问题答案: 不,在Java中-甚至在v5之前的C#中,都没有等效的异步/等待方式。 在后台构建状态机是一项相当复杂的语言功能。 Java中对异步/并发的 语言 支持相对较少,但是该软件包包含许多与此相关的有用 类 。(不完全等同于任

  • 我通读了Dart/flatter中的Async/Await/then,试图理解为什么aysnc函数中的Await不会等到完成后再继续。在我的UI中,有一个按钮调用一个异步方法来返回一个位置,该位置总是返回null,并且不等待函数完成。 该函数将调用推送到一个新的UI页面,该页面选择一个位置,并应返回一个结果。如何使该函数等待结果?我不是在使用异步吗?

  • 在实际应用中,我对 C# 中的异步和 await 方法进行了说明。请考虑以程,这是工作代码的简单版本: 助手.cs 功能控制器.cs processing.js 现在,问题是第三方服务的所需时间更少(例如:2秒),而所需的时间更多(例如:100秒)。进行两个ajax调用并使用异步和等待是为了呈现自我。屏幕上显示数据1,不要等到自己。Data2已被检索。不幸的是,这种情况没有发生,我必须等待100秒

  • 问题内容: 我使用Node.js和TypeScript,并且使用。这是我的测试用例: 我想为整个功能设置一个超时时间。即如果要花费2秒,花费0.5秒,花费5秒,我想在3秒钟后让我抛出错误的超时。 正常调用是一个问题,因为范围丢失了: 而且我不能用普通的方式抓住它: 有关如何解决的任何想法? 问题答案: 您可以使用超时: 您必须将其包装在诺言中才能使用。