2013-03-11 22 views
5

当我创建一个任务,如何在C#中获取TPL任务线程的引用?

Task task = Task.Factory.StartNew(() => someMethod(args)); 
在C#4.0 +

,我怎么能得到这个任务的线程(S)的参考?

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

更新:
的原因是:

  • 我想,以确定任务的线程调试器(和它的属性的名称)等

创建任务执行总是与创建任务的线程分离?
它是一个,零个还是多个线程?
它在同一个核心上执行吗?
知道,因为,例如,我可以把睡在主线程的思想,我冻结了后台工作是很重要的

更新:
有用的答案:

+5

你不应该需要做的风险。你想解决什么问题? – SLaks 2013-03-11 14:07:36

+1

据我所知,你不能那样做。不能保证任务会产生一个新的线程,它可以运行在它创建的同一个线程上。此外,任务(可能)可以在多个线程之间分割。但是我在这里和@SLaks在一起,关于这种方法有些问题。 – 2013-03-11 14:08:32

+0

答案:(1)肯定,但为什么,(2)是,(3)是。 – user7116 2013-03-11 14:08:45

回答

7

创建的任务总是在创建任务的独立线程中执行吗?

不,有某些情况下在其中TPL能够确定该任务可以创建它的同一线程上执行,或者是因为相关的任务创建选项(或任务调度程序)时,供给或作为优化,因为调用线程否则不会有任何事情要做。尽管如此,你并不需要担心。这不像你最终会阻止UI线程,因为TPL选择在该上下文中执行它的代码。除非你明确表明它不应该发生。对于所有的意图和目的,你可以假定这种事情从来没有发生过(除非你强迫它发生),但在幕后,没有你需要意识到它,是的,它可能发生。

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

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

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

可能但不是确定。

知道,因为,例如,我可以把睡在主线程的思想,我冻结了后台工作

把主线程睡眠会防止后台是非常重要的工作的工作人员。这就是整个创建后台工作者,这两项任务不会阻止彼此做工。请注意,如果后台工作人员尝试访问UI以报告进度或显示结果,并且UI被阻止,那么他们将等待UI线程在该点处免费。

+1

+1,OP的另一个关于在调试器中查找任务的问题,我将它们指向['Task.Id' /'Task.CurrentId'](http://msdn.microsoft.com/zh-cn/library/ system.threading.tasks.task.id.aspx)(MSDN注释的是调试器)和[Parallel Tasks窗口](http://msdn.microsoft.com/en-us/library/dd998369.aspx)。 – user7116 2013-03-11 16:25:55

3

您可以使用:

System.Threading.Thread.CurrentThread 

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

3

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

在.Net 4中,默认的TaskScheduler使用ThreadPool执行任务(请参见here),因此如果一个ThreadPool线程排队该任务,那么相同的线程稍后可能会执行该任务。

线程数量由ThreadPool决定。

你不应该在乎你的任务在哪个核心上执行。

排队执行任务将最有可能安排它要在一个线程池线程执行的,所以你不会在意外把主线程设置

+0

如果没有指定* default *任务调度程序(使用线程池的任务调度程序),则不使用当前任务调度程序。 – Servy 2013-03-11 14:56:11

+1

不符合MSDN文档。它说调用Factory.StartNew()相当于创建一个Task并调用Task。开始()使用当前。查看我的帖子中的链接。 – SpaceghostAli 2013-03-11 15:01:34

相关问题