After reading up on inlining in the TPL from sources like here, I got the impression that a call to Task.Wait() will start a task that hasn't yet begun (at least using the default scheduler). However, writing up a quick demo like:
var taskB = new Task(
() =>
{
Console.WriteLine("In TaskB");
System.Threading.Thread.Sleep(5000);
Console.WriteLine("Leaving TaskB");
});
var taskA = new Task(
() =>
{
Console.WriteLine("In TaskA");
System.Threading.Thread.Sleep(500);
Console.WriteLine("Waiting on TaskB");
taskB.Wait();
Console.WriteLine("Leaving TaskA");
});
taskA.Start();
taskA.Wait();
Causes a deadlock. TaskA gets to the taskB.Wait() line, but taskB is never started. I haven't messed with the scheduler or anything, so I'm not really sure why the .Wait() call on taskB wouldn't cause it to start.
Wait()
does not cause a task to Start()
. If you call Wait()
on an unstarted task, it will wait for it to begin and complete until it completes, the wait timed out or the wait is cancelled. Since your call to Wait()
does not contain a cancellation token or timeout, it's an infinite for the task to complete.
I think what's confusing you from the blog is this line:
However, if it hasn’t started executing, Wait may be able to pull the target task out of the scheduler to which it was queued and execute it inline on the current thread.
The key here is the phrase "hasn't started executing". This does not mean that Start()
was not called, but that Start()
was called, which schedules the task and makes it ready to execute, but the task hasn't begun to execute.
Start()
is necessary to schedule a task for execution, it doesn't immediately begin execution. That's the main point of that blurb. If the task is ready to go but not scheduled, it may be inlined. But it won't start a task that hasn't even been scheduled.
If you look at TaskStatus
in the MSDN (See here) you see the following values:
When you create the task (with new or factory), it is in Created
state. Nothing happens to a task in this state. Once it is started, then it moves to WaitingForActivation
and so on, at THIS point until it reaches Running
, its possible according to that blog that it could be inlined.
So, long story short, creating a task just puts it in Created
state and won't make it start if Wait()
is called. Make sense?
The inlining mentioned in that article is different than a Task starting. Waiting on a task does not start it - which can be demonstrated very easily. Just try the following:
namespace Test
{
using System;
using System.Threading.Tasks;
internal class TestCompile
{
private static void Main(string[] args)
{
Task t = new Task(() => Console.WriteLine("Executed!"));
t.Wait(5000);
Console.WriteLine("After wait...");
Console.ReadKey();
}
}
}
You'll see that the task never starts...
A call to task.Wait()
will not start a task. It will cause the Task to execute immediately and "inline" on the current thread (with the default scheduler) if:
The third point there is fuzzy - it can execute inline on a different scheduler, but this requires the other scheduler to be able to execute it immediately, so it's dependent on the scheduler being one that supports this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With