This is a pretty subtle question, but my curiosity got the best of me, and I couldn't find the answer in the docs, or elsewhere on SO.
The docs for Task.Wait(int millisecondsTimeout)
say:
Waits for the Task to complete execution within a specified number of milliseconds.
It returns:
true
if the Task completed execution within the allotted time; otherwise,false
.
Consider this snippet:
Task task = Task.Run(() => {
Thread.Sleep(2000);
});
task.Wait(1000);
Does the timeout countdown start immediately when I call Task.Wait(...)
, or does Wait(...)
first wait for the Task to actually start running before kicking off the countdown? (Task.Run(...)
only makes the Task eligible to run. It doesn't guarantee that it's actually started)
For example, if all the threads in the threadpool are in use, and the thread pool has to delay by, say, 0.5 seconds before creating a new thread for my queued-Task, will my Wait(1000)
call return after the full second, or after 0.5 seconds?
If I were to guess, I would say that Wait(...)
will return after the full second, but I want to make sure.
Since by my reading, it would be easy enough for you to test the scenario to find out for yourself, I'm not really sure I'm actually understanding what you're asking. That said, here's how I would test it:
static void Main(string[] args)
{
Task task = new Task(() => WriteLine("task!"));
task.Wait(1000);
WriteLine("Done waiting");
}
And sure enough, if you run the above code, you'll find that even though you've never started the task, the call to Wait()
will still expire after 1 second.
In other words, just as the documentation says, the method waits for up to the time specified for the task to complete, and then returns.
Given that the Wait()
method will return even if the task's never even been started, that it will also return if the task's been started, but hasn't been given a chance to run any code yet. It sounds like that's actually the scenario you were asking about.
Whether the task starts or not is irrelevant (though, in practice we almost never have unstarted tasks these days…good idiomatic C# programming practices dictate that you only get a Task
object from mechanisms that return an already-started task, such as Task.Run()
or calling an async
method).
Or look at it this way: if your mom tells you, "I'll serve dinner as soon as you're done cleaning your room, but no later than 30 minutes from now", do you think she'll take into consideration whether you've actually started cleaning your room or not? No, she's going to serve dinner in 30 minutes, no matter what.
Same thing with .NET. It doesn't care if you started the task or not, just that it didn't complete within the allotted time.