我在 C# 中摆弄 async/await 只是为了深入研究一些线程控制流,并偶然发现了一个不寻常的行为,我非常感谢对此的澄清。
即使任务本身在后台执行,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”线程。但我实际上正在努力寻找一些与此相关的明确信息。
简而言之,当SynchronizationContext.Current
没有设置,(控制台应用程序就是这种情况)。等待响应被调用ThreadPool
.
在 Winforms/WPF 上,实现 SynchronizationContext 来对 winforms 的响应进行排队controlToSendTo.BeginInvoke();
或 WPFDispatcher.BeginInvoke();
.
参考:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)