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

本文关键字:任务 线程 参考 TPL 获取 | 更新日期: 2023-09-27 18:03:32

创建任务

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

在c# 4.0+中,我如何获得这个任务的线程的引用?

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


更新:原因如下:

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

创建的任务是否总是在与创建任务的线程分开的线程中执行?
是一个、零个还是多个线程?
它是在同一个核心上执行的吗?
知道这一点很重要,因为,例如,我可以让主线程休眠,认为我正在冻结后台工作线程


更新:实用答案:

  • 在使用Task时指定线程名。StartNew

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

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

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

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

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

是否在同一个核心上执行?

有可能,但不一定。

知道这一点很重要,因为,例如,我可以让主线程休眠,认为我正在冻结后台worker

让主线程进入睡眠状态将会而不是阻止后台工作线程继续工作。这就是创建后台工作线程的全部,这两个任务不会阻止彼此工作。请注意,如果后台工作线程试图访问UI来报告进度或显示结果,并且UI被阻塞,那么它们将等待UI线程在那个时候空闲。

您可以使用:

System.Threading.Thread.CurrentThread

但是正如评论中所说,您使用TPL抽象线程,所以回到这个"低级别"可能是一个糟糕的设计指标。

task . factory . startnew()将任务排队等待执行(见这里)。执行任务的实际线程及其执行时间取决于指定的TaskScheduler(如果未指定则使用当前TaskScheduler)。

在。net 4中,默认的TaskScheduler使用ThreadPool来执行任务(见这里),所以如果一个ThreadPool线程将任务排队,那么同一个线程可以稍后执行它。

线程数由ThreadPool决定。

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

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