每个新的System.Threading.Tasks.Task()都会创建一个新线程吗?

时间:2014-08-22 12:58:32

标签: c# .net multithreading .net-4.0 .net-4.5

我只是想弄明白,因为我正在使用Task对象来让我的时间在一个单独的通道中运行。但我想知道Task(()=>{...})是否与创建new Thread(new ThreadStart(()=>{....}))类似?

3 个答案:

答案 0 :(得分:3)

Task表示将来某个时间完成的承诺工作。

如何创建Task有几个选项:

  1. 使用Task.RunTask.Factory.StartNew没有任何标志 - 如上所述,这将在.NET ThreadPool上排队工作。

  2. 使用Task.Factory.StartNew并指定TaskCreationOptions.LongRunning - 这将表示TaskScheduler使用新线程而不是ThreadPool线程。

  3. 使用C#-5的async-await功能时,也称为Promise Tasks。当您await返回TaskTask<T>的方法时,他们可能不会使用任何线程机制,ThreadPool或new Thread来完成他们的工作,因为他们可能使用纯粹的异步API,这意味着它们将继续在执行它们的线程上执行,并且一旦命中第一个await关键字,就会将控制权交还给调用方法。

  4. 感谢Servy这个。另一个执行选项是创建自定义TaskScheduler并将其传递给Task.Factory.StartNew。自定义TaskScheduler可让您对Task

  5. 的执行进行细粒度控制

    所有这些选项都表明Task仅仅是一种承诺,而且有许多形式可以实现这一承诺。线程是达到目的的手段,而Task是我们想要完成的工作单元。

答案 1 :(得分:2)

简答:否。任务通过线程池执行。这是一个关于此的博客:Threads vs. Tasks:任务不会创建自己的操作系统线程。相反,任务由TaskScheduler执行;默认调度程序只在ThreadPool上运行

答案 2 :(得分:2)

可能。这取决于。

  • 使用TaskTask.Run或使用Task.Factory.StartNew构造函数创建的默认Task个对象将使用默认的TaskSchedluer,安排委托在线程池中运行。

  • 非默认TaskScheduler可用于安排任务在您使用该调度程序定义的任何线程上运行。您可以将其定义为在UI线程中运行,在其自己的新线程中运行,在.NET线程池之外的线程池中运行,根本不运行,或者您想要的任何其他内容。

  • 您可以使用Task创建TaskCompletionSource,其中根本不需要存在线程。 Task甚至不需要代表委托的完成。它可以表示将来某个时间完成的任何操作,可能会产生结果。 可能涉及在线程上运行的某些代码,或者它可能代表一种固有的异步操作,例如IO,用户行为,事件触发,各种其他任务的组合或您想要的任何其他任务创建