简体   繁体   English

C#异步和等待不起作用

[英]C# Async and Wait Not Working

Why is the following async and await not working? 为什么以下asyncawait不起作用? 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. 程序开始启动count()方法,但未完成就退出。 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. 我希望它在退出之前等待它完成count()方法的所有循环(0、1、2、3、4)。 I only get "count loop: 0". 我只得到“计数循环:0”。 But it is going through all of callCount(). 但是它正在经历所有的callCount()。 Its like await task isn't doing anything. 就像等待任务一样,它什么也没做。 I want both count() and callCount() to run asynchronously and return to main when complete. 我希望count()和callCount()都异步运行,并在完成后返回main。

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. 当您执行async方法时,它开始同步运行直到到达await语句,然后其余代码异步执行,执行返回给调用者。

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. 在您的代码中, callCount()开始同步运行以await task ,然后返回Main()方法,并且由于您不等待该方法完成,因此该程序将在方法count()无法完成的情况下结束。

You can see the desired behavior by changing the return type to Task , and calling Wait() in Main() method. 通过将返回类型更改为Task ,并在Main()方法中调用Wait() ,可以看到所需的行为。

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 ) (为更好地理解,让我们将CallCount()返回类型更改为Task

  1. the program starts with Main() method. 该程序以Main()方法开始。
  2. CallCount() method is called. CallCount()方法。
  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. 此时,将创建一个并行运行Count()方法的新线程。
  5. Execution continues in CallCount(), for loop is executed and "just before await" is printed. 在CallCount()中继续执行,执行for循环并打印“就在等待之前”。
  6. Then await task; 然后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. awaitWait() ,它不会阻塞当前线程,直到任务完成,而是将执行控制返回给Main()方法和CallCount()所有剩余指令(在这种情况下,仅是Console.WriteLine("callCount completed"); )将在任务完成后执行。
  7. In Main() , the call to CallCount() returns a Task (with the remaining instructions of CallCount() and the original task) and execution continues. Main() ,对CallCount()的调用返回一个Task (带有CallCount()的其余指令和原始任务),并继续执行。
  8. If you dont wait for this task to finishes, the execution in Main() will continue finalizing the program and the tasks being destroyed. 如果您不等待此任务完成, Main()的执行将继续完成程序,并销毁任务。
  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. 如果您调用Wait() (如果CallCount()为空,则您没有要等待的任务),则让任务完成,将其保留在Main()以执行Count()并打印“ callCount完成”。

If you want to wait for count task finishes in CallCount() without returning to Main() method, call task.Wait(); 如果要在CallCount()等待计数任务完成而没有返回Main()方法,请调用task.Wait(); , all the program will wait for Count() , but this is not what await will do. ,所有程序将等待Count() ,但这不是await要做的。

This link explains async-await pattern in details. 链接详细说明了异步等待模式。

Hopes this workflow diagram of your code helps you. 希望此代码工作流程图对您有所帮助。

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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