首页 > 解决方案 > “等待”什么时候会立即离开一个方法,什么时候不会?

问题描述

在使用 async-await 的程序中,我的理解是这样的:

下面的应用程序是我编写的,以检查上述陈述是否正确。

using System;
using System.Threading.Tasks;

namespace ConsoleApp3
{
    class Program
    {
        static async Task Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            DoJob();

            var z = 3;

            Console.ReadLine();
        }

        static async Task DoJob()
        {
            var work1 = new WorkClass();
            var work2 = new WorkClass();

            while (true)
            {
                await work1.DoWork(500);
                await work2.DoWork(1500);
            }
        }
    }

    public class WorkClass
    {
        public async Task DoWork(int delayMs)
        {
            var x = 1;

            await Task.Delay(delayMs);

            var y = 2;
        }
    }
}

以下是我的一些观察:

我不明白的事情:

标签: c#multithreadingasynchronousasync-awaittask

解决方案


为什么等待 Task.Delay(delayMs); 离开 DoJob 方法,但等待 work1.DoWork(500); 才不是?

因为这段代码:

await work1.DoWork(500);

与此代码相同:

var task = work1.DoWork(500);
await task;

因此,您的代码首先调用该方法,然后等待返回的任务。通常将其await称为“等待方法调用”,但这并不是实际发生的情况 - 从技术上讲,方法调用首先(同步)完成,然后等待返回的任务。

我看到 DoJob 正在正常执行。我认为它会在后台完成(可能是由线程池线程之一?)。

不; 对于真正的异步操作,没有线程在该操作上被阻塞。

如果它是某种长时间运行的方法,看起来它可能会阻塞线程,对吗?

是的。

我的理解是这样的

我建议阅读我的异步介绍以获得更好的心理框架。总之:

  1. async启用await关键字。它还生成一个状态机来处理创建Task返回值之类的东西。
  2. await对“等待”(通常是任务)进行操作。首先,它检查它是否已经完成;如果是,则该async方法继续同步执行。
  3. 如果 awaitable 尚未完成,则await(默认情况下)捕获其上下文并async在 awaitable 完成时安排继续在该上下文上运行的方法。

推荐阅读