5

当我创建一个任务时

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

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

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

更新:
原因是:

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

创建的任务是否总是在与创建任务的线程不同的线程中执行?
它是一个、零个还是多个线程?
它是在同一个内核上执行的吗?
重要的是要知道,例如,我可以让主线程进入睡眠状态,以为我正在冻结后台工作人员

更新:
有用的答案:

4

3 回答 3

8

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

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

它是一个、零个还是多个线程?

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

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

有可能,但不一定。

重要的是要知道,例如,我可以让主线程进入睡眠状态,以为我正在冻结后台工作程序

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

于 2013-03-11T14:36:35.250 回答
4

您可以使用:

System.Threading.Thread.CurrentThread

但是正如评论中所说,您使用 TPL 来抽象线程,因此回到这个“低级别”可能是设计不佳的一个指标。

于 2013-03-11T14:12:11.683 回答
3

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

在 .Net 4 中,默认的 TaskScheduler 使用 ThreadPool 来执行任务(请参见此处),因此如果 ThreadPool 线程将任务排队,则同一线程可能稍后会执行它。

线程数由 ThreadPool 决定。

您不应该真正关心您的任务在哪个核心上执行。

排队执行任务很可能会将其安排在 ThreadPool 线程上执行,因此您不会有意外使主线程进入睡眠状态的风险

于 2013-03-11T14:40:08.137 回答