为了账号安全,请及时绑定邮箱和手机立即绑定

异步.NET控制台程序中的线程控制流

异步.NET控制台程序中的线程控制流

C#
慕仙森 2022-12-31 10:35:19
我在 C# 中弄乱了 async/await 只是为了深入研究一些线程控制流并偶然发现了一个不寻常的行为,我真的很感谢澄清。即使 Task 本身在后台执行,await 之后的执行也会在调用线程上继续执行,这是有道理的。事实上,这正是发生在 WPF 中的情况。以下代码:private async void Button_Click(object sender, RoutedEventArgs e){    Console.WriteLine($"Start. Thread: {Thread.CurrentThread.ManagedThreadId}");    await Task.Run(async () => await Task.Delay(1000));    Console.WriteLine($"End. Thread: {Thread.CurrentThread.ManagedThreadId}");}结果:开始。线程:1结束。线程:1我意识到这是使程序流可预测等的方法。但令我惊讶的是 .NET 控制台应用程序的异步 Main 方法功能显示出有些不同的行为。相同的代码:static async Task Main(string[] args){    Console.WriteLine($"Start. Thread: {Thread.CurrentThread.ManagedThreadId}");    await Task.Run(async () => await Task.Delay(1000));    Console.WriteLine($"End. Thread: {Thread.CurrentThread.ManagedThreadId}");}导致不同的线程控制流程:启动。线程:1结束。线程:5我的猜测是,控制台应用程序具有不同的同步上下文概念,并且不像 WPF 那样绑定到主“UI”线程。但我实际上正在努力寻找一些明确的信息。
查看完整描述

1 回答

?
千巷猫影

TA贡献1829条经验 获得超7个赞

简而言之,当SynchronizationContext.Current未设置时,(控制台应用程序就是这种情况)。在 上调用 await 响应ThreadPool

controlToSendTo.BeginInvoke();在 Winforms/WPF 上,实现了 SynchronizationContext 以将对 winforms或 WPF的响应排队Dispatcher.BeginInvoke();

参考:

  • Await、SynchronizationContext 和控制台应用程序(开发团队成员的博客文章):

    但是有一种常见的应用程序没有SynchronizationContext:控制台应用程序。当您的控制台应用程序的Main方法被调用时,SynchronizationContext.Current将返回null. 这意味着如果您在控制台应用程序中调用一个异步方法,除非您做一些特殊的事情,否则您的异步方法将没有线程亲和力:这些异步方法中的延续最终可能会“在任何地方”运行。

  • Parallel Computing - It's All About the SynchronizationContext(这篇文章引用自该类的官方文档SynchronizationContext):

    默认情况下,控制台应用程序和 Windows 服务中的所有线程都只有默认的SynchronizationContext.

    ...

    图 4SynchronizationContext实施摘要
    ...

╔═════════╦═══════════╦════════════╦════════════╦══════════╦══════════╗

║         ║ Specific  ║ Exclusive  ║ Ordered    ║ Send May ║ Post May ║

║         ║ Thread    ║ (Delegates ║ (Delegates ║ Invoke   ║ Invoke   ║

║         ║ Used to   ║ Execute    ║ Execute    ║ Delegate ║ Delegate ║

║         ║ Execute   ║ One at     ║ in Queue   ║ Directly ║ Directly ║

║         ║ Delegates ║ a Time)    ║ Order)     ║          ║          ║

╠═════════╬═══════════╬════════════╬════════════╬══════════╬══════════╣

║ ...     ║           ║            ║            ║          ║          ║

╠═════════╬═══════════╬════════════╬════════════╬══════════╬══════════╣

║ Default ║ No        ║ No         ║ No         ║ Always   ║ Never    ║

╚═════════╩═══════════╩════════════╩════════════╩══════════╩══════════╝


查看完整回答
反对 回复 2022-12-31
  • 1 回答
  • 0 关注
  • 75 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信