5

When I create a task as

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

in C# 4.0+, how can I get the reference of the thread(s) of this task?

Is it possible that the task is executed in the same thread that created the task or spawn more than one thread?

Update:
The reasons are:

  • I'd like to identify the task's thread in debugger (and attribute a name for it), etc.

Is created task executed always in separate thread from the one in which a task was created?
Is it one, zero or more than one thread?
Is it executed on a single and the same core?
It is important to know since, for example, I can put to sleep the main thread thinking that I am freezing the background worker

Update:
Useful answer:

Community
  • 1
  • 1
Fulproof
  • 4,466
  • 6
  • 30
  • 50
  • 5
    You should never need to do that. What problem are you trying to solve? – SLaks Mar 11 '13 at 14:07
  • 1
    As far as I know, you can't do that. There's no guarantee that the task will spawn a new thread, it can run on the same thread it was created on. Also the task (probably) can be split between multiple threads. But I'm with @SLaks here, there's something off regarding this approach in general. – Patryk Ćwiek Mar 11 '13 at 14:08
  • The answers: (1) sure but why, (2) yes, (3) yes. – user7116 Mar 11 '13 at 14:08
  • What is the reason you are thinking about doing that ? What is your target ? The number and reuse of threads isn't predictable from an outside point of view. Also more thread don't necessarly mean working faster.. For example if you only have one single core cpu and the only thing you are doing calulating then each additional thread would be a waste of ressources. Also Spawning threads costs time and ram, some times this costs more then the benefit of using multiple cpus – Boas Enkler Mar 11 '13 at 14:11
  • @ sixlettervariables, can you put you comment in answer having identified the questions to which you answered by (1), (2) and (3)? – Fulproof Mar 11 '13 at 14:37
  • 2
    If you assign a name to that thread the name will persist over the duration of your task. Other tasks might share the same thread name which will be confusing. I wish there was a way to name tasks though. – usr Mar 11 '13 at 14:43

3 Answers3

8

Is created task executed always in separate thread from the one in which a task was created?

No, there are certain situations in which the TPL is able to determine that the task can be executed on the same thread that created it, either because the relevant task creation option (or task scheduler) was supplied, or as an optimization because the calling thread would otherwise not have anything to do. You don't really need to worry about this though; it's not like you're going to end up blocking the UI thread because the TPL choose to execute it's code in that context. That won't happen unless you specifically indicate that it should. For all intents and purposes you can assume that this never happens (unless you force it to happen) but behind the scenes, without you ever needing to realize it, yes, it can happen.

Is it one, zero or more than one thread?

By default, tasks are executed in the thread pool. The thread pool will vary in the number of threads it contains based on the workload it's given. It will start out at one, but grow if there is sufficient need, and shrink if that need disappears. If you specify the LongRunning option, a new thread will be created just for that Task. If you specify a custom TaskScheduler, you can have it do whatever you want it to.

Is it executed on a single and the same core?

Potentially, but not assuredly.

It is important to know since, for example, I can put to sleep the main thread thinking that I am freezing the background worker

Putting the main thread to sleep will not prevent background workers from working. That's the whole point of creating the background workers, the two tasks don't stop each other from doing work. Note that if the background workers ever try to access the UI either to report progress or display results, and the UI is blocked, then they will be waiting for the UI thread to be free at that point.

Servy
  • 202,030
  • 26
  • 332
  • 449
  • 1
    +1, the OP's other question about finding the Task in the debugger I would point them to [`Task.Id`/`Task.CurrentId`](http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.id.aspx) (which MSDN notes is there for Debuggers) and the [Parallel Tasks window](http://msdn.microsoft.com/en-us/library/dd998369.aspx). – user7116 Mar 11 '13 at 16:25
4

You can use:

System.Threading.Thread.CurrentThread

But as said in the comments, you use the TPL to abstract threading away, so going back to this "low level" is a likely indicator of poor design.

Louis Kottmann
  • 16,268
  • 4
  • 64
  • 88
3

Task.Factory.StartNew() queues the task for execution (see here). The actual thread that executes the task and when it gets executed is up to the TaskScheduler specified (the current TaskScheduler is used if none is specified).

In .Net 4 the default TaskScheduler uses the ThreadPool to execute tasks (see here) so if a ThreadPool Thread queued the task the same thread can possibly execute it later on.

The number of threads is dictated by the ThreadPool.

You shouldn't really care about which core your tasks are executed on.

Queuing a Task for execution will most likely schedule it to be executed on a ThreadPool Thread so you won't be at risk of accidentally putting the main thread to sleep

HasaniH
  • 8,232
  • 6
  • 41
  • 59
  • The *default* task scheduler (the one that uses the thread pool) is used if none is specified, not the current task scheduler. – Servy Mar 11 '13 at 14:56
  • 1
    Not according to the MSDN documentation. It says calling Factory.StartNew() is equivalent to creating a Task and calling Task.Start() which uses the current. See the links in my post. – HasaniH Mar 11 '13 at 15:01