简体   繁体   中英

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.

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 until the task finishes, but returns the execution control to the Main() method and all remaining instructions in CallCount() (in this case just Console.WriteLine("callCount completed"); ) will be executed after the task is completed.
  7. In Main() , the call to CallCount() returns a Task (with the remaining instructions of CallCount() and the original task) and execution continues.
  8. If you dont wait for this task to finishes, the execution in Main() will continue finalizing the program and the tasks being destroyed.
  9. If you call Wait() (if CallCount() is void you dont have a task to wait for) you let the task to complete, holding in Main() for Count() execution and "callCount completed" being printed.

If you want to wait for count task finishes in CallCount() without returning to Main() method, call task.Wait(); , all the program will wait for Count() , but this is not what await will do.

This link explains async-await pattern in details.

Hopes this workflow diagram of your code helps you.

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM