I was reading Jeffrey Richter's clr via c# book and felt uncomfortable reading that task wait may not always wait and I quote
"When a thread calls the Wait method, the system checks if the Task
that the thread is waiting for has started executing. If it has, then
the thread calling Wait will block until the Task has completed
running. But if the Task has not started executing yet, then the
system may (depending on the TaskScheduler ) execute the Task by
using the thread that called Wait . If this happens, then the thread
calling Wait does not block; it executes the Task and returns
immediately."
Can some one please share more insight and in which case can such a scenario may happen?
I think this is unfortunately phrased. It's not that the Wait
call returns before the task has finished executing; it's that the thread calling Wait
may end up executing the task itself, rather than just blocking idly.
Sample code:
using System;
using System.Threading;
using System.Threading.Tasks;
class Test
{
static void Main()
{
// Make sure DemonstrateIssue is already called in a ThreadPool
// thread...
Task task = Task.Run((Action) DemonstrateIssue);
task.Wait();
}
static void DemonstrateIssue()
{
Console.WriteLine("DemonstrateIssue thread: {0}",
Thread.CurrentThread.ManagedThreadId);
Action action = () => Console.WriteLine("Inner task thread: {0}",
Thread.CurrentThread.ManagedThreadId);
Task task = new Task(action);
// Calling Start will just schedule it... we may be able to Wait
// before it actually executed
task.Start();
task.Wait();
}
}
Output every time I've run it:
DemonstrateIssue thread: 3
Inner task thread: 3
This takes advantage of the fact that the thread pool doesn't spin up threads immediately on demand - it waits for a while to see if an existing thread will become available before starting another one. If you add Thread.Sleep(5000);
before the call to task.Wait()
, you'll see the two tasks end up on different threads.