异步.NET控制台程序中的线程控制流程[重复]

问题描述 投票:2回答:1

我在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控制台应用程序的异步主方法功能显示了一些不同的行为。 相同的代码:

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个回答
3
投票

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

在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 from SynchronizationContext类的官方文档): 默认情况下,控制台应用程序和Windows服务中的所有线程仅具有默认的SynchronizationContext。 ... 图4 SynchronizationContext实现的摘要 ... ╔═════════╦═══════════╦════════════╦════════════╦═ ═══════════════════╗║║║║║║║║║║║║║║║May MayMay║║║║║║║║║║║║Deleg║║║║║║║║║║Deleg Deleg Deleg Deleg Deleg Deleg Deleg Deleg Deleg Deleg Deleg Deleg Deleg Deleg Deleg Deleg Deleg Deleg Deleg Deleg Deleg Deleg Deleg Deleg Deleg Deleg DelegDeleg║Deleg Deleg Deleg Deleg Deleg Deleg Deleg DelegDeleg║║║║║║║║║║║║║║║║║║║║║║║║║║║║║║║║║║║║║║║ ║用于║执行║执行║代表║代表║║║执行║一个在队列中的║直接║直接║║║代表║a时间║命令)║║║╠══════════╬ ═══════════╬════════════╬════════════╬══════════╬═ ══════════╣║║║║║║║══════════════════════════════════════════════════════════════════════════════ ═════╬════════════╬══════════╬═══════ ══╣╣默认║否║否║否║始终║从不║║════════════════════════════════════════════════════════════════════════════════════ ═╩════════════╩══════════╩══════════╝
© www.soinside.com 2019 - 2024. All rights reserved.