c# – 如果异步方法是单线程的,它怎么能在后台运行?

我正在尝试理解async / await并阅读了大量文章,但我仍然对同步/异步性质感到困惑.

我有以下测试控制台应用程序:

static void Main(string[] args)
{
    var test = FooAsync();
    Console.WriteLine("After FooAsync");

    for (int i = 0; i < 100; i++)
        Console.WriteLine("After that");

    Console.ReadKey();
}

private static async Task FooAsync()
{
    Console.WriteLine("Before delay");
    await Task.Delay(1);
    Console.WriteLine("After delay");
}

代码提供了以下行的输出

Before delay
After FooAsync
After that
After that
After that
After that
After delay
After that
.
.

我知道async / await不会创建一个单独的线程进行处理,并且当FooAsync到达await Task.Delay(1)行时,它将返回Main,因为任务还没有完成,但是,因为我们是只有在单个线程上运行才能解释是什么触发FooAsync方法在Main之前的某个任意点恢复,然后Main可以继续?

更新
我把它拿回来,i3arnon和dariogriffo是正确的.代码确实使用了多个线程(正如我之前看到的那样,在调试器中查看或完成了kha建议的显而易见的事情).我对下一页https://msdn.microsoft.com/en-us/library/hh191443.aspx#BKMK_Threads中的“线程”部分感到困惑,没有意识到“延续”实际上是指一旦“等待”任务完成就立即运行的继续任务计划.

解决方法

这不是单线程的.

当延迟任务完成时,方法的其余部分将发布到ThreadPool并与主线程同时运行.这里的“触发器”是在Task.Delay中使用的内部System.Threading.Timer的回调.

此行为取决于SynchronizationContext.在UI环境中,这将被发布到相同的UI线程,并且必须等到该线程空闲.

如果您一直在等待从FooAsync返回的任务,那么每次只能运行一个线程.

相关文章

目录简介使用JS互操作使用ClipLazor库创建项目使用方法简单测...
目录简介快速入门安装 NuGet 包实体类User数据库类DbFactory...
本文实现一个简单的配置类,原理比较简单,适用于一些小型项...
C#中Description特性主要用于枚举和属性,方法比较简单,记录...
[TOC] # 原理简介 本文参考[C#/WPF/WinForm/程序实现软件开机...
目录简介获取 HTML 文档解析 HTML 文档测试补充:使用 CSS 选...