调用anon异步Func与使用Task.Factory直接调用之间的区别?

时间:2016-04-13 19:44:45

标签: c# asynchronous

这两段代码之间的区别是什么? 如果我们有以下匿名函数:

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();

从本质上讲,它们都是异步执行的,但是赞成另一种方式的专业人员是什么?他们都返回任务。返回的任务有何不同? (例如是一个多线程,而另一个是单线程等)。

1 个答案:

答案 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