Why is the following async
and await
not working? I am trying to learn this would like to understand what is wrong with my code.
class Program
{
static void Main(string[] args)
{
callCount();
}
static void count()
{
for (int i = 0; i < 5; i++)
{
System.Threading.Thread.Sleep(2000);
Console.WriteLine("count loop: " + i);
}
}
static async void callCount()
{
Task task = new Task(count);
task.Start();
for (int i = 0; i < 3; i++)
{
System.Threading.Thread.Sleep(4000);
Console.WriteLine("Writing from callCount loop: " + i);
}
Console.WriteLine("just before await");
await task;
Console.WriteLine("callCount completed");
}
}
The program goes starts the count() method but drops out without completing it. With the await task; statement I was expecting it to wait to complete all loops of the count() method (0, 1, 2, 3, 4) before exiting. I only get "count loop: 0". But it is going through all of callCount(). Its like await task isn't doing anything. I want both count() and callCount() to run asynchronously and return to main when complete.
When you execute an
async
method, it starts running synchronously until it reaches anawait
statement, then the rest of the code executes asynchronously, and execution return to the caller.In your code
callCount()
starts running synchronously toawait task
, then back toMain()
method, and since you are not waiting for the method to complete, the program ends without methodcount()
can finish.You can see the desired behavior by changing the return type to
Task
, and callingWait()
inMain()
method.EDIT: This is how your code executes:
(for better understanding lets changes
CallCount()
return type toTask
)Main()
method.CallCount()
method is called.Count()
method in parallel.await task;
is reached. This is when async-await pattern plays its role.await
is not likeWait()
, it doesn't block the current thread until the task finishes, but returns the execution control to theMain()
method and all remaining instructions inCallCount()
(in this case justConsole.WriteLine("callCount completed");
) will be executed after the task is completed.Main()
, the call toCallCount()
returns aTask
(with the remaining instructions ofCallCount()
and the original task) and execution continues.Main()
will continue finalizing the program and the tasks being destroyed.Wait()
(ifCallCount()
is void you dont have a task to wait for) you let the task to complete, holding inMain()
forCount()
execution and "callCount completed" being printed.If you want to wait for count task finishes in
CallCount()
without returning toMain()
method, calltask.Wait();
, all the program will wait forCount()
, but this is not whatawait
will do.This link explains async-await pattern in details.
Hopes this workflow diagram of your code helps you.