c#异步任务:是否所有参与的方法都必须是异步的?
本文关键字:异步 方法 任务 是否 | 更新日期: 2023-09-27 18:06:05
当我们处理异步任务时,任务由多个方法调用(可能是其他类的)组成,这些方法调用又由进一步的方法调用组成。我们可以称它为树。是否所有的方法都必须是类型异步任务的原始任务真正异步行为?对于其他类似语言(主要是Java)的任何类型的后台任务,答案是正确的吗?(在c#中,一旦我在这个树中的某个地方有一个方法进入无限循环(谈论一个长时间运行的任务!),然而遗憾的是,原始异步任务的isRunning属性返回false。)
是否所有的方法都必须是async task类型的原始任务真正异步行为?
为了异步操作,async
方法必须有一个await
语句用于一个尚未完成的操作。
我想我的async
介绍博客会对你有帮助。
这个答案是否适用于其他类似语言的任何类型的后台任务,主要是Java ?
是的。
遗憾的是,原始异步任务的isRunning属性返回false
我认为你的意思是TaskStatus
不是TaskStatus.Running
。这是正常和预期的,因为异步任务是承诺任务,而不是委托任务(查看我的博客了解更多信息)。
简短的回答是否定的。异步意味着由另一个进程完成的工作可以被传递给该进程,因此不会阻塞调用线程。如果这些进程不在同一台机器上,那就更好了,因为这些工作在调用者处占用的计算或IO很少。这是通过使用async/await机制挂起方法执行来实现的,该机制承诺一旦完成就在某些同步上下文上恢复。那么,为什么要进行概述呢?
因为这意味着我们可以而且应该明智地选择那些应该是异步的操作,因此在异步方法中应用await关键字。有些不需要它,因为它们是轻量级的,并且由于异步状态机的创建,向它们添加异步甚至可能会增加计算时间。因此,方法中的操作通常可以是异步和同步代码的混合。
这反过来意味着一些方法将使用async/await的Task返回类型,而一些方法将是常规的同步方法。
不,他们不需要。简单的例子,在一个表单应用程序中
button.Click += async (_, __) =>
{
await Task.Run(() => MyClass.SomeTimeconsumingMethod());
};
仍然允许您在执行SomeTimeconsumingMethod
期间移动窗口,而这个
button.Click += (_, __) =>
{
MyClass.SomeTimeconsumingMethod();
};
不允许你这么做
使用await
关键字的唯一要求是您正在等待的方法返回Task
或Task<T>
。
这个方法的确切实现(async
或return someTask
)对代码的正确性没有影响,尽管它可能会影响函数。
任何正常的代码都可以在async
方法中与await
调用一起运行。唯一重要的限制是不允许使用out
和ref
。
是否所有的方法都必须是async task类型才能使原始任务真正异步?
这取决于你所说的"all"这个词是什么意思。
一些api不能是异步的。以List<T>.Add
为例。你真的希望它是异步的吗?
有些api应该是异步的,但是没有相应的异步api(例如SMO或File
静态类)。
理想情况下你应该做"异步所有的方式",当谈论io绑定操作。但是,当async
方法链的某些部分将同步执行io绑定操作时,IRL可能会面临违反此规则的情况。