下面的等待任务尚未完成await
点并且它不捕获 UI 上下文。这意味着后面的 UI 修改代码将在另一个线程(本例中为线程池线程)中调用。
private async void Button1_Click(object sender, EventArgs e)
{
StringBuilder sb = new StringBuilder();
sb.Append($"{Thread.CurrentThread.ManagedThreadId}, ");
Task t = Task.Delay(1000);
await t.ConfigureAwait(false);
sb.Append($"{Thread.CurrentThread.ManagedThreadId}");
Text = sb.ToString();
}
上面的代码运行没有任何问题。运行时没有错误。
Question
为什么允许在非UI线程中修改UI组件?
难道是我的理解有问题?
除非附加了调试器,否则 winforms 中默认禁用跨线程检查。这个可以看到在初始化时checkForIllegalCrossThreadCalls field:
private static bool checkForIllegalCrossThreadCalls = Debugger.IsAttached;
如果我不得不猜测,我会说这是为了保持复古兼容性。 .NET 1.1 没有跨线程检查(当时我还想知道为什么我的应用程序会在几个小时后神秘地崩溃),它们是随 .NET 2.0 添加的。但这是一个巨大的突破性变化,我想这就是他们选择加入的原因。对于 WPF,立即引入了跨线程检查,因此他们可以为每个人激活它们。
鉴于此,我强烈建议在任何 winform 项目中手动启用跨线程检查,方法是将这一行添加到入口点:
[STAThread]
static void Main()
{
Control.CheckForIllegalCrossThreadCalls = true;
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)