【发布时间】:2019-04-19 09:41:30
【问题描述】:
下面的 awaitable 没有在 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();
}
上面的代码运行没有任何问题。运行时没有错误。
问题
为什么允许在非UI线程中修改UI组件? 我的理解有问题吗?
【问题讨论】:
-
好的,知道了。它与附加的调试器一起崩溃,没有它就可以工作。看起来只有在附加了调试器时才会在 Winform 上默认激活跨线程检查:referencesource.microsoft.com/#System.Windows.Forms/winforms/…
-
添加
Control.CheckForIllegalCrossThreadCalls = true;会导致即使没有调试器也会崩溃,正如预期的那样 -
@TheodorZoulias 好吧,您可以(并且可能应该)将
Control.CheckForIllegalCrossThreadCalls = true;添加到您的项目中。我理解为什么默认情况下不启用它,但我想知道他们为什么不将它添加到新项目模板中。 -
@KevinGosse:你应该把它作为你的答案。我会接受的。谢谢!
-
当我们在那里时,我打开了一个问题,看看这是否可以在 .net 核心中修复:github.com/dotnet/winforms/issues/832