【问题标题】:Does C# Async/Await work like interrupt?C# Async/Await 是否像中断一样工作?
【发布时间】:2017-02-10 08:33:20
【问题描述】:

我这样测试控制台应用程序:

class Program
{
    static void Main(string[] args)
    {
        Test();

        Console.WriteLine("C");

        Console.ReadLine();
    }

    static async void Test()
    {
        Console.WriteLine("A");
        await Task.Delay(2000);
        Console.WriteLine("B");
    }
}

此应用程序立即打印 A 和 C,然后在 2 秒后打印 B。看起来不错。但是我读了一篇关于 async/await "There Is No Thread" (http://blog.stephencleary.com/2013/11/there-is-no-thread.html) 的文章,它说 async/await 不会创建额外的线程。

所以回到我的控制台应用程序,我认为主线程在 Console.ReadLine() 上被阻塞,所以 Test() 中的剩余代码 (Console.WriteLine("B")) 直到 Console.ReadLine 才会执行() 做完了。但实际结果不同,不管主线程是否阻塞,都会执行剩下的代码。

我想知道 await 像 CPU 中断一样工作,所以指令指针移动到剩余代码(Console.WriteLine("B");) 并在之后移回中断位置(Console.ReadLine();)执行?

【问题讨论】:

  • async/await 是异步工作的抽象。在某些情况下实现基于 CPU 中断,在某些情况下它基于 EPOLL,在某些情况下它可以基于线程同步原语。
  • @KichangKim:There Is No Thread 解释了异步如何必须使用线程,并且对于 I/O 操作,它通常不会阻塞线程。但是,当异步方法继续时,它必须在某个地方运行;我在async intro post 中描述了这种行为。

标签: c# multithreading asynchronous async-await


【解决方案1】:

与 Windows 窗体应用程序不同,控制台应用程序没有单一的“祝福”线程(UI 线程)。因此,默认情况下,在控制台应用程序中没有使用特殊的synchronization context,因此await 使用的延续实际上是使用线程池调度的。

因此,无需“中断”当前在 Console.ReadLine 上等待的线程 - 而是使用另一个线程。

【讨论】:

    猜你喜欢
    • 2019-12-04
    • 2021-12-18
    • 2017-10-24
    • 2015-11-15
    • 1970-01-01
    • 2010-12-29
    • 1970-01-01
    • 2021-08-09
    相关资源
    最近更新 更多