C# 异步任务:所有参与的方法也必须是异步的吗?
当我们处理异步任务时,任务由多个方法调用(可能是其他类的)组成,而这些方法调用又由更多的方法调用组成。我们可以称之为树。是否所有方法都必须是async task类型,原始任务才能真正表现为async? 对于其他类似语言(主要是Java)的任何背景任务,答案都是正确的吗?C# 异步任务:所有参与的方法也必须是异步的吗?,c#,async-await,C#,Async Await,当我们处理异步任务时,任务由多个方法调用(可能是其他类的)组成,而这些方法调用又由更多的方法调用组成。我们可以称之为树。是否所有方法都必须是async task类型,原始任务才能真正表现为async? 对于其他类似语言(主要是Java)的任何背景任务,答案都是正确的吗? (在C#中,一旦我将我的一个方法放在这棵树的某个地方,就会进入一个无限循环(谈论一个长时间运行的任务!),但遗憾的是,原始异步任务的isRunning属性返回false。)使用wait关键字的唯一要求是等待的方法返回一个任务或任
(在C#中,一旦我将我的一个方法放在这棵树的某个地方,就会进入一个无限循环(谈论一个长时间运行的任务!),但遗憾的是,原始异步任务的isRunning属性返回false。)使用
wait
关键字的唯一要求是等待的方法返回一个任务
或任务
此方法(async
或returnsometask
)的确切实现不会影响代码的正确性,尽管它可能会影响函数
任何普通代码都可以在
async
方法中与wait
调用一起运行。唯一重要的限制是不允许out
和ref
。简短的回答是否定的。异步意味着由另一个进程完成的工作可以交给该进程,因此不会阻塞调用线程。如果这些进程不驻留在同一台机器上就更好了,因为这项工作将占用调用方很少的计算或IO。这是通过使用async/await机制暂停方法执行来实现的,该机制承诺在完成后在某些同步上下文上恢复。那么,为什么要概述
因为这意味着我们可以而且应该明智地选择那些应该是异步的操作,因此在异步方法中应用await关键字。有些人不需要它,因为它们是轻量级的,向它们添加异步甚至可能会由于创建异步状态机而增加计算时间。因此,方法中的操作通常可以是异步代码和同步代码的混合
这反过来意味着有些方法将使用async/await的任务返回类型,有些方法将是常规的同步方法。不,它们不必这样做。简单示例,在表单应用程序中
button.Click += async (_, __) =>
{
await Task.Run(() => MyClass.SomeTimeconsumingMethod());
};
仍然允许您在执行SomeTimeconsumingMethod
期间移动窗口,而
button.Click += (_, __) =>
{
MyClass.SomeTimeconsumingMethod();
};
不让你这么做
是否所有方法都必须是async task类型,原始任务才能真正表现为async
这取决于你所说的“全部”是什么意思
某些API不能是异步的。考虑一下列表。例如,添加。您真的希望它是异步的吗?
有些API应该是异步的,但没有异步的对应项(例如,或静态类)
理想情况下,在讨论IO绑定操作时,您应该“一路异步”。但是当async
方法链的某些部分将同步执行IO绑定操作时,您可能会面临违反此规则的IRL
是否所有方法都必须是async task类型,原始任务才能真正表现为async
为了异步运行,async
方法必须为尚未完成的操作使用await
语句
我想我的建议会对你有所帮助
对于其他类似语言(主要是Java)的任何背景任务,答案都是正确的吗
对
遗憾的是,原始异步任务的isRunning属性返回false
我想您的意思是TaskStatus
不是TaskStatus.Running
,由于异步任务是(有关更多信息,请参阅我的博客)。您应该向我们提供您尝试过的代码片段。您的意思是,该方法中的所有其他方法都可以是任何类型的?从技术上讲,您需要一个返回可等待的结果的方法。请参阅:@heinzbeinz在向学习者解释async/Wait时,我试图省略特定的鸭子类型的恐怖表演。这是不必要的细节。@Gusdor,你这样说完全正确。我只是想添加waitiable作为参考。@heinzbeinz也非常感谢,不过,有趣的是知道我在任务方面有更多的自由。我想问题是async
和Task
的组合是否是启用异步执行的机制,不是所有的代码都应该async@DvS我的意思是,调用链中的所有方法都必须是异步的,还是只有“第一个”方法。也许我的等待方法停止运行是因为它是在新线程中启动的<代码>分析线程=新线程(异步()=>等待a.analyze(afile,someID,arg3))代码>为异步工作启动一个新线程是非常不寻常的(async
代码很可能在线程池线程上恢复,而不是在自定义线程上)。如果要在线程池上下文上运行异步工作,请使用Task.run
而不是thread
。