While Task.Delay is what you would normally like to use instead (so you don’t lose thread during sleep), your problem is not really related to this.
What happens here when you submit a printout of the results, you get access to the Result property for each task. This blocks the execution of the task, so you wait 5 seconds in WaitAll, and then another 5 seconds when you print the result of the 10 second task.
In accordance with your stated intention, you need to check the status of the task before accessing the result, since your intention is not to block it, but only print it if it is already completed:
int[] results = new int[tasks.Length]; for (int i = 0; i < tasks.Length; i++) { if (tasks[i].IsCompleted) { Console.WriteLine(tasks[i].Result); } }
By the way, you can show that “block on Result” is what happens in the source code by simply adding some simple time checks (for example, using a stopwatch, for example)
Task<int>[] tasks = new Task<int>[] { Task.Factory.StartNew<int>(()=> { Thread.Sleep(10000); return 1; }), Task.Factory.StartNew<int>(()=> { Thread.Sleep(3000); return 2; }) }; TimeSpan timeSpan = new TimeSpan(0, 0, 5); var stopwatch = Stopwatch.StartNew(); Task.WaitAll(tasks, timeSpan); Console.WriteLine("WaitAll took {0} seconds", stopwatch.Elapsed.TotalSeconds); int[] results = new int[tasks.Length]; for (int i = 0; i < tasks.Length; i++) { stopwatch = Stopwatch.StartNew(); Console.WriteLine(tasks[i].Result); Console.WriteLine("Printing result took {0} seconds", stopwatch.Elapsed.TotalSeconds); }
This gives console output:
WaitAll took 4.9996961 seconds 1 Printing result took 5.0050012 seconds 2 Printing result took 0.0004338 seconds
source share