1

I understand that the TPL does not necessarily create a new thread for every task in a parallel set, but does it always create at least one? eg:

private void MyFunc()
{
    Task.Factory.StartNew(() =>
    {
        //do something that takes a while   
    });

    DoSomethingTimely();   //is this line guaranteed to be hit immediately?
}

EDIT: To clarify: Yes, I mean is it guaranteed that the thread executing MyFunc() is not going to be used to execute //do something that takes a while.

GazTheDestroyer
  • 20,722
  • 9
  • 70
  • 103
  • 1
    It sounds like you're not asking your real question. Why do you care if a new thread is created? What does "immediately" mean in this context? – David Schwartz Feb 23 '12 at 10:20

6 Answers6

7

That's up to whatever the current default TaskScheduler is. You can just about envisage someone doing something horrific like implementing a SynchronousTaskScheduler that executes the task body during QueueTask and sets it to complete before returning.

Assuming you're not letting someone else muck about with your task schedulers, you shouldn't have to worry about it.

Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448
  • +1 I would upvote this twice, if I could, because it is the only answer right now that even mentions the `TaskScheduler` class. – Christian.K Feb 23 '12 at 10:41
5

It depends on what you mean by "immediately" but I think it's reasonable to assume that the TPL isn't going to hijack your currently executing thread to synchronously run the code in your task, if that's what you mean. At least not with the normal scheduler... you could probably write your own scheduler which does do so, but you can normally assume that StartNew will schedule the task rather than just running it inline.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Has this changed for .NET 4.5? Because I had this exact situation occur and TPL did use the currently executing thread to execute the task. – Cameron MacFarland Aug 02 '13 at 07:06
  • @CameronMacFarland: There are a *very few* situations where that will happen - but not in the example shown in the code above. In particular, if you wait for a task directly after you've started it (before it actually starts executing), and you're already in a thread-pool thread, I believe that *can* reuse the thread. – Jon Skeet Aug 02 '13 at 07:09
  • Nevermind. Turns out a task can execute on the same thread it's started on, if the task is created within another task. See http://richnewman.wordpress.com/2012/11/21/why-starting-a-new-task-in-the-task-parallel-library-tpl-doesnt-always-start-a-new-thread/ EDIT: Yep, that's what happened. – Cameron MacFarland Aug 02 '13 at 07:12
  • @CameronMacFarland: It can execute on the same thread, but I don't believe it would *hijack* the current thread to do so. The page you were referring to actually seems to be more about scheduling continuations than anything else - which is very different. – Jon Skeet Aug 02 '13 at 07:14
  • Hmmm, good point. I'm not sure then why code that was working in 4.0 broke in 4.5. But it was due to the task executing on the UI thread when it shouldn't have. – Cameron MacFarland Aug 02 '13 at 07:22
2

Your main question and the question in your code are completely different questions. But the answers to the two questions are:

1) No, there's no guarantee a thread will be started. What is created and started is a task. Ultimately, some thread will have to execute that task, but whether one will be created is unspecified. An existing thread could be re-used.

2) It depends what you mean by "immediately". Strictly speaking, there is no timeliness guarantee. But you have told the system to execute that task, and it will at least start it as soon as it finishes everything it considers more important. Strict fairness or timeliness is not guaranteed.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
1

Yes, it will hit very shortly after dispatching the task to run.

No, it will not create a new thread, but claim one. When they say it doesn't always create a new thread, they are referring to the fact that it re-uses threads from a thread pool.

The size of the pool is based on the number of CPU cores detected. But it will always contain at least 1 thread. ;)

Tyson
  • 14,726
  • 6
  • 31
  • 43
1

In short: Yes, this is guranteed.

Longer: If StartNew() does not create a new thread, it will reuse another: Either by it being free, or by queueing.

Eugen Rieck
  • 64,175
  • 10
  • 70
  • 92
0

DoSomethingTimely will get called very quickly, but what does that have to do with creating a new thread, or adding the task to a queue?

zmbq
  • 38,013
  • 14
  • 101
  • 171