C#异步和等待不起作用 [英] C# Async and Wait Not Working

查看:101
本文介绍了C#异步和等待不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么以下asyncawait不起作用?我试图学习这是想了解我的代码有什么问题.

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");
    }
}

程序继续启动count()方法,但未完成就退出.完成等待任务;我期望它在退出之前等待它完成count()方法的所有循环(0、1、2、3、4).我只得到计数循环:0".但是它正在经历所有的callCount().就像等待任务一样,它什么也没做.我希望count()和callCount()都异步运行,并在完成后返回main.

解决方案

执行async方法时,它开始同步运行,直到到达await语句,然后其余代码异步执行,然后执行返回到呼叫者.

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

通过将返回类型更改为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");
}

这是您的代码执行的方式:

(为更好地理解,让更改CallCount()将返回类型更改为Task)

  1. 程序以Main()方法开头.
  2. CallCount()方法被调用.
  3. 任务创建完毕,所有任务都在同一线程中.
  4. 然后任务开始.此时,将创建一个并行运行Count()方法的新线程.
  5. 在CallCount()中继续执行,执行循环并打印就在等待之前".
  6. 然后到达await task;.这是异步等待模式起作用的时候. awaitWait()不同,它不会阻塞当前线程,直到任务完成,而是将执行控制返回给Main()方法和CallCount()中的所有其余指令(在本例中为Console.WriteLine("callCount completed"); )将在任务完成后执行.
  7. Main()中,对CallCount()的调用返回一个Task(带有CallCount()的其余指令和原始任务)并继续执行.
  8. 如果您不等待此任务完成,则Main()中的执行将继续完成程序并销毁任务.
  9. 如果调用Wait()(如果CallCount()为空,则您没有要等待的任务),则让任务完成,按住Main()以便执行Count(),并打印"callCount已完成".

如果要等待CallCount()中的计数任务完成而没有返回Main()方法,请调用task.Wait();,所有程序将等待Count(),但这不是await会执行的操作.

链接详细介绍了异步等待模式. >

希望此代码工作流程图对您有所帮助.

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 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.

这篇关于C#异步和等待不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆