jaykum February 2016

C# Async and Wait Not Working

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.

Answers


Arturo Menchaca February 2016

When you execute an async method, it starts running synchronously until it reaches an await statement, then the rest of the code executes asynchronously, and execution return to the caller.

In your code callCount() starts running synchronously to await task, then back to Main() method, and since you are not waiting for the method to complete, the program ends without method count() can finish.

You can see the desired behavior by changing the return type to Task, and calling Wait() in Main() method.

static void Main(string[] args)
{
    callCount().Wait();
}

static void count()
{
    for (int i = 0; i < 5; i++)
    {
        System.Threading.Thread.Sleep(2000);
        Console.WriteLine("count loop: " + i);
    }
}

static async Task callCount()
{
    Task task = new Task(count);
    task.Start();
    for (int i = 0; i < 3; i++)
    {
        System.Threading.Thread.Sleep(1000);
        Console.WriteLine("Writing from callCount loop: " + i);
    }
    Console.WriteLine("just before await");
    await task;
    Console.WriteLine("callCount completed");
}

EDIT: This is how your code executes:

(for better understanding lets changes CallCount() return type to Task)

  1. the program starts with Main() method.
  2. CallCount() method is called.
  3. the task is created, all this in the same thread.
  4. Then the task is started. At this point, a new thread is created running Count() method in parallel.
  5. Execution continues in CallCount(), for loop is executed and "just before await" is printed.
  6. Then await task; is reached. This is when async-await pattern plays its role. await is not like Wait(), it doesn't block the current thread unt

Post Status

Asked in February 2016
Viewed 2,294 times
Voted 7
Answered 1 times

Search




Leave an answer