c# - 从 await 返回后的意外行为

标签 c# asynchronous async-await

我知道有很多关于 async/await 的问题,但我找不到任何答案。

我遇到了一些我不明白的东西,请考虑以下代码:

void Main()
{
    Poetry();
    while (true)
    {
        Console.WriteLine("Outside, within Main.");
        Thread.Sleep(200);
    }
}

async void Poetry()
{
   //.. stuff happens before await
   await Task.Delay(10);
   for (int i = 0; i < 10; i++)
   {
       Console.WriteLine("Inside, after await.");
       Thread.Sleep(200);
   }
}

显然,在 await 运算符上,控制权返回给调用者,而正在等待的方法正在后台运行。 (假设一个IO操作)

但是在控制权返回到 await 运算符之后,执行变为并行,而不是(我的期望)保持单线程。

我希望在“Delay”完成后线程将被强制返回 Poetry 方法,从它离开的地方继续。

它是做什么的。对我来说奇怪的是,为什么“Main”方法一直在运行?那个线程是从一个线程跳到另一个线程吗?还是有两个并行线程?

又是线程安全问题吗?

我觉得这很困惑。我不是专家。谢谢。

最佳答案

我有一个 description on my blog of how async methods resume after an await .本质上,await 捕获当前的 SynchronizationContext 除非它是 null,在这种情况下它捕获当前的 TaskScheduler。然后使用该“上下文”来安排该方法的其余部分。

由于您正在执行控制台应用程序,因此没有 SynchronizationContext,并且会捕获默认的 TaskScheduler 以执行 async 的其余部分> 方法。该上下文将 async 方法排队到线程池。除非您实际为控制台应用程序提供一个带有 SynchronizationContext(或 TaskScheduler)的主循环,否则无法返回到该主循环的主线程。

关于c# - 从 await 返回后的意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20445933/

相关文章:

具有可为空日期时间的 C# 空条件运算符

c# - 使用私有(private)还是使用属性? C#

C# 将静态类放入字典中

javascript - 当所有数据加载时如何运行函数?

c# - 保存工具条的用户位置在 VS2012 中仍然不起作用

javascript - 异步错误卡住网站

c# - 创建一个在总线上包装订阅和发布的异步方法

c# - 如何在不使用 Task.Delay 或 await 的情况下编写异步方法

c# - 在 ICommand 上实现 INotifyPropertyChanged

node.js - 异步/等待错误返回 Promise { <pending> }