如何在C#中获取TPL任务的线程参考?

时间:2013-03-11 14:06:39

标签: c# .net multithreading concurrency task-parallel-library

当我创建任务时

Task task = Task.Factory.StartNew(() => someMethod(args));

在C#4.0+中,我如何获得此任务的线程的引用?

是否可能在创建任务的同一线程中执行任务或生成多个线程?

更新:
原因是:

  • 我想在调试器中识别任务的线程(并为其命名属性)等。

创建的任务是否始终在与创建任务的线程不同的线程中执行? 是一个,零个还是多个线程?
它是在同一个核心上执行的吗? 重要的是要知道,因为,例如,我可以睡觉主线程,认为我冻结了后台工作者

更新:
有用的答案:

3 个答案:

答案 0 :(得分:7)

  

创建的任务是否始终在与创建任务的线程不同的线程中执行?

不,在某些情况下,TPL能够确定任务可以在创建它的同一个线程上执行,因为提供了相关的任务创建选项(或任务调度程序),或者作为优化因为调用线程否则无法做任何事情。你不需要担心这个问题;它不会像你最终阻止UI线程,因为TPL选择在该上下文中执行它的代码。除非您明确指出应该这样做,否则不会发生这种情况。对于所有意图和目的,你可以假设这种情况永远不会发生(除非你强迫它发生)但是在幕后,你不需要意识到它,是的,它可能发生。

  

是一个,零个还是多个线程?

默认情况下,任务在线程池中执行。根据给定的工作负载,线程池的线程数会有所不同。它将从一开始,但如果有足够的需求则增长,如果需要消失则缩小。如果指定LongRunning选项,则只为该Task创建一个新线程。如果您指定自定义TaskScheduler,则可以让它执行您想要的任务。

  

它是在同一个核心上执行的吗?

潜在但不确定。

  

重要的是要知道,因为,例如,我可以睡觉主线程,认为我冻结了后台工作者

将主线程置于休眠状态阻止后台工作者工作。这是创建后台工作者的整个,这两个任务不会相互阻止工作。请注意,如果后台工作人员尝试访问UI以报告进度或显示结果,并且UI被阻止,那么他们将等待UI线程在此时空闲。

答案 1 :(得分:4)

您可以使用:

System.Threading.Thread.CurrentThread

但正如评论中所说,你使用TPL抽象线程,所以回到这个“低级别”可能是设计不良的指标。

答案 2 :(得分:3)

Task.Factory.StartNew()将任务排队等待执行(参见here)。执行任务的实际线程以及执行任务的时间取决于指定的TaskScheduler(如果没有指定,则使用当前的TaskScheduler)。

在.Net 4中,默认的TaskScheduler使用ThreadPool来执行任务(参见here),这样如果一个ThreadPool线程对该任务进行了排队,那么同一个线程可能会在以后执行它。

线程数由ThreadPool决定。

您不应该真正关心执行任务的核心。

排队执行任务很可能会安排它在ThreadPool线程上执行,这样你就不会有意外将主线程置于睡眠状态的风险