Having created the following console application I am a little puzzled why it seems to run synchronously instead of asynchronously:
class Program
{
static void Main(string[] args)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
var total = CreateMultipleTasks();
stopwatch.Stop();
Console.WriteLine("Total jobs done: {0} ms", total.Result);
Console.WriteLine("Jobs done in: {0} ms", stopwatch.ElapsedMilliseconds);
}
static async Task<int> CreateMultipleTasks()
{
var task1 = WaitForMeAsync(5000);
var task2 = WaitForMeAsync(3000);
var task3 = WaitForMeAsync(4000);
var val1 = await task1;
var val2 = await task2;
var val3 = await task3;
return val1 + val2 + val3;
}
static Task<int> WaitForMeAsync(int ms)
{
Thread.Sleep(ms);
return Task.FromResult(ms);
}
}
When running the application, output is:
Total jobs done: 12000 ms
Jobs done in: 12003 ms
I would have expected somehing like:
Total jobs done: 12000 ms
Jobs done in: 5003 ms
Is this because when I use the Thread.Sleep method it stops further execution of the whole application? Or am I missing something important here?
Even when you convert to using
Task.Run
orTask.Delay
as other answers suggest, you should avoid using the blockingTask.WaitAll
anywhere insideasync
methods, as much as you can. Mixing asynchronous and synchronous code is usually a bad idea, it increases the number of redundantly blocked threads and promotes deadlocks.Instead, use
await Task.WhenAll
and move the blocking wait to the top level (i.e.,Main
method in this case):On a side note, check Stephen Toub's "Should I expose asynchronous wrappers for synchronous methods?" and "Should I expose asynchronous wrappers for synchronous methods?"
You run the task in a synchounus manner. You can do something like this:
Using the three
await
in a row will NOT run the tasks in parallel. It will just free the thread while it is waiting (if you useawait Task.Delay(ms)
asThread.Sleep(ms)
is a blocking operation), but the current execution will NOT continue withtask2
whiletask1
is "sleeping".Your WaitForMeAsync method is just a simple sync method pretending to be an async one.
You don't perform anything async and Sleep() just blocks the thread.
Why would you want to delay async? (yes you can use
await Task.Delay(ms)
), need more input to help there.