【问题标题】:Why are we allowed to modify the form title from a thread pool thread? [duplicate]为什么允许我们从线程池线程修改表单标题? [复制]
【发布时间】: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

标签: c# winforms


【解决方案1】:

除非附加了调试器,否则在 winforms 中默认禁用跨线程检查。这个可以看in the initialization of the 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());
}

【讨论】:

  • 它有一个(微不足道的)性能成本。启用CheckForIllegalCrossThreadCalls 后,更新FormText 属性会慢4%。 :-)
  • 我认为一个好的折衷方案是使用预处理器指令:#if DEBUG Control.CheckForIllegalCrossThreadCalls = true; #万一。在发布应用程序之前,我应该能够在开发过程中发现并修复这些错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-22
  • 2012-07-26
  • 1970-01-01
  • 2011-01-03
  • 1970-01-01
  • 2023-02-11
  • 2010-11-14
相关资源
最近更新 更多