【问题标题】:Thread control flow in async .NET Console program [duplicate]异步.NET控制台程序中的线程控制流[重复]
【发布时间】:2019-09-14 16:10:57
【问题描述】:

我在 C# 中搞乱 async/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”线程。但我实际上正在努力寻找一些明确的信息。

【问题讨论】:

标签: c# .net async-await threadpool


【解决方案1】:

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

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

参考:

  • Await, SynchronizationContext, and Console Apps(开发团队的博文by a member):

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

  • Parallel Computing - It's All About the SynchronizationContext(一篇文章referenced fromSynchronizationContext类的官方文档):

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

    ...

    图 4 SynchronizationContext 实现摘要
    ...

    ╔═════════╦═══════════╦═════════════════════════════ ═╦══════════╦══════════╗
    ║ ║ 特定 ║ 独家 ║ 已订购 ║ 5 月发送 ║ 5 月发布 ║
    ║║线程║(委托║(委托║调用║调用║
    ║ ║ 习惯 ║ 执行 ║ 执行 ║ 委托 ║ 委托 ║
    ║ ║ 执行 ║ 队列中的 ║ 一个 ║ 直接 ║ 直接 ║
    ║║代表║一次)║顺序)║║║
    ╠═════════╬═══════════╬════════════╬════════════╬═ ═════════╬══════════╣
    ║ ... ║ ║ ║ ║ ║ ║
    ╠═════════╬═══════════╬════════════╬════════════╬═ ═════════╬══════════╣
    ║ 默认 ║ 否 ║ 否 ║ 否 ║ 总是 ║ 从不 ║
    ╚═════════╩═══════════╩════════════╩════════════╩═ ═════════╩══════════╝

【讨论】:

  • 你增加了一些价值@GSeg。太好了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-11
  • 1970-01-01
  • 2016-11-02
  • 2013-08-26
  • 2017-04-10
  • 2010-10-30
相关资源
最近更新 更多