C# Async and Wait Not Working

后端 未结 1 1661
别那么骄傲
别那么骄傲 2021-01-03 10:30

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.

c         


        
1条回答
  •  时光说笑
    2021-01-03 10:48

    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 inMain() 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.

    0 讨论(0)
提交回复
热议问题