为什么允许我们从线程池线程中修改表单标题? [英] Why are we allowed to modify the form title from a thread pool thread?

查看:22
本文介绍了为什么允许我们从线程池线程中修改表单标题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的 awaitable 不会在 await 点完成,也不会捕获 UI 上下文.这意味着后面的 UI 修改代码将在另一个线程(在本例中为线程池线程)中调用.

The awaitable below does not complete at the await point and it does not capture the UI context. It means the UI modifying code that follows will be invoked in another thread (thread pool thread in this case).

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();
}

上面的代码运行没有任何问题.运行时没有错误.

The code above runs without any problem. No error at runtime.

为什么允许在非 UI 线程中修改 UI 组件?我的理解有问题吗?

Why is it allowed to modify UI components in non-UI thread? Is there something wrong with my understanding?

推荐答案

除非附加了调试器,否则在 winforms 中默认禁用跨线程检查.这可以在初始化中看到 checkForIllegalCrossThreadCalls 字段:

Cross-thread checks are disabled by default in winforms unless the debugger is attached. This can be seen in the initialization of the checkForIllegalCrossThreadCalls field:

private static bool checkForIllegalCrossThreadCalls = Debugger.IsAttached;

如果非要我猜的话,我会说这是一种保持复古兼容性的尝试..NET 1.1 没有跨线程检查(当时我一直想知道为什么我的应用程序会在几个小时后神秘崩溃),它们是随 .NET 2.0 一起添加的.但这是一个巨大的突破性变化,我想这就是他们选择加入的原因.使用 WPF,立即引入了跨线程检查,因此他们可以为每个人激活它们.

If I had to guess, I'd say this is an attempt to preserve retro-compatibility. .NET 1.1 did not have cross-thread checks (and back in the days I was left wondering why my apps would mysteriously crash after a few hours), they were added with .NET 2.0. But this is a huge breaking change, and I suppose that's why they made it opt-in. With WPF, cross-thread checks were introduced right-away, so they could activate them for everybody.

有鉴于此,我强烈建议在任何 winform 项目中手动启用跨线程检查,方法是在入口点添加以下行:

In light of this, I strongly recommend to enable cross-thread checks manually in any winform project by adding this line to the entry-point:

[STAThread]
static void Main()
{
    Control.CheckForIllegalCrossThreadCalls = true;

    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
}

这篇关于为什么允许我们从线程池线程中修改表单标题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆