这两段代码之间的区别是什么? 如果我们有以下匿名函数:
Func<object, Task<bool> foo = async (str) => { /*misc async code with awaits*/ return result};
直接调用它之间的区别是什么:
Task<bool> bar = foo("myparam");
并使用任务:
Task<bool> bar = Task.Factory.StartNew(foo, "myparam").Unwrap();
从本质上讲,它们都是异步执行的,但是赞成另一种方式的专业人员是什么?他们都返回任务。返回的任务有何不同? (例如是一个多线程,而另一个是单线程等)。
答案 0 :(得分:2)
从本质上讲,它们都是异步执行的,但是赞成另一种方式的专业人员是什么?
直接调用该方法将在当前线程上异步执行。被调用的方法将继承调用方法的上下文,并将使用当前SynchronizationContext
(或者,如果是null
,当前TaskScheduler
)继续执行。 I explain this in full on my blog
通过StartNew
调用方法将在当前TaskScheduler
上异步执行。通常,这是线程池任务调度程序,除非调用代码作为Delegate Task(我的博客中定义的术语)的一部分执行。除非该任务是started with the HideScheduler
option(在我的博客中描述),在这种情况下,即使有TaskScheduler
执行该代码,也没有当前的TaskScheduler
。
如果StartNew
场景听起来很复杂,那就是因为它。 StartNew
仅适用于专家。我在why StartNew
should not be used上发布了一篇完整的博文。
更直观的比较是直接调用方法和通过Task.Run
调用方法。与StartNew
不同,Task.Run
总是在线程池线程上执行其代码,因此该方法将在线程池上异步运行。
对于真实世界的代码,您应该只在需要时使用Task.Run
。如果该方法是正确异步的(即,它不首先计算分形或任何东西),那么你不应该使用Task.Run
。你根本不应该使用StartNew
。