C#异步任务:所有参与的方法都必须是异步的吗?

时间:2016-09-07 09:16:24

标签: c# async-await

当我们处理异步任务时,任务包含多个方法调用(可能是其他类),而这些调用又包含更多的方法调用。我们可以称之为树。是否所有方法都必须是原始任务的异步任务类型才能真正表现为异步? 对于其他类似语言的任何背景任务,主要是Java,答案是否正确? (在C#中,一旦我在这个树的某个地方使用了我的一个方法进入一个无限循环(谈论一个长期运行的任务!),但遗憾的是,原始异步任务的isRunning属性返回false。)

5 个答案:

答案 0 :(得分:3)

  

所有方法都必须是原始任务的异步任务类型才能真正表现为异步吗?

为了表现异步,async方法必须有一个await语句,用于尚未完成的操作。

我认为我的async intro blog post会对您有所帮助。

  

对于其他类似语言的任何后台任务,主要是Java,答案是否正确?

  遗憾的是,原始的异步任务isRunning属性返回false

我认为您的意思是TaskStatus不是TaskStatus.RunningThis is normal and expected,因为异步任务是Promise Tasks, not Delegate Tasks(有关详细信息,请参阅我的博客)。

答案 1 :(得分:2)

简短的回答是否定的。异步意味着主线程不会被它在调用链中进一步执行的代码阻塞。主线程可以等待,也可以立即返回。那么,确定异步的是主线程是否异步执行依赖代码,通过在await方法上使用async的机制,或使用Task.Run()之类的东西。

答案 2 :(得分:1)

不,他们不必。简单的例子,在Forms应用程序中这个

button.Click += async (_, __) =>
                {
                    await Task.Run(() => MyClass.SomeTimeconsumingMethod());
                };

仍允许您在执行SomeTimeconsumingMethod期间移动窗口,而这一个

button.Click += (_, __) =>
                {
                    MyClass.SomeTimeconsumingMethod();
                };

不允许你这样做。

答案 3 :(得分:0)

使用await关键字的唯一要求是,您正在等待的方法会返回TaskTask<T>

此方法的确切实现(asyncreturn someTask)对代码的正确性没有影响,尽管它可能会影响函数。

任何普通代码都可以async方式与await方法一起运行。唯一重要的限制是不允许使用outref

答案 4 :(得分:0)

  

所有方法都必须是原始任务的异步任务类型才能真正表现为异步

这取决于你的意思&#34; 所有&#34;字。

某些API不能是异步的。例如,考虑List<T>.Add。你真的希望它是异步的吗? 有些API应该是异步的,但是没有异步对应物(例如SMOFile静态类)。

理想情况在谈论IO绑定操作时,你应该做到#34;异步#34;但是当您的async方法链的某些部分同步执行IO绑定操作时,IRL可能会违反此规则。