c# - 设置 WinForms.Form 所有者时出现跨线程异常 - 如何正确执行?

标签 c# winforms invoke

我有一个主 UI 线程,它运行应用程序并创建主窗口窗体(我们称它为 W)。我还有一个辅助线程,我启动它并创建一个对话框(我们称它为 B)。

我想将对话框 B 的所有者设置为主窗口 WB 所有者的设置发生在创建 B 的线程上。基本上:

b.Owner = w;

但这会抛出一个跨线程异常,告诉我我正在尝试从错误的线程访问 W 对象。

所以我尝试通过在 W 上使用 Control.Invoke 来在主 UI 线程上执行代码。但是,我得到了同样的错误,告诉我我正在尝试从错误的线程访问 B:

System.InvalidOperationException was unhandled by user code
  Message=Cross-thread operation not valid: Control 'B' accessed from a
  thread other than the thread it was created on.
  Source=System.Windows.Forms

我应该怎样做才正确?

最佳答案

这是Winforms的一个小bug,Windows实际上支持让所有者成为在另一个线程上创建的窗口。有一种方法可以禁用该检查,这是您绝不应该做的事情。除非你不得不我想:

    private void button1_Click(object sender, EventArgs e) {
        var t = new Thread(() => {
            Control.CheckForIllegalCrossThreadCalls = false;
            var frm = new Form2();
            frm.Show(this);
            Control.CheckForIllegalCrossThreadCalls = true;
            Application.Run(frm);
        });
        t.SetApartmentState(ApartmentState.STA);
        t.Start();
    }

不知道是否知道这是否 100% 安全,Winforms 交互可能会把事情搞砸。你在这里未经测试的水域,有线程鲨鱼出没。

关于c# - 设置 WinForms.Form 所有者时出现跨线程异常 - 如何正确执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5273674/

相关文章:

c# - 使用函数或表达式替换 "new {x.ID,x.Name}"部分

c# - WCF 流式下载 - IIS 与控制台中托管的 CPU 利用率较高

c# - 如何在 ListView 中对整数进行排序

c# - 按钮数组 : change property

java - Mule:如何将Java/Spring bean的方法调用结果分配给流变量

c# - 从 C# 调用 PowerShell cmdlet 会引发 CommandNotFoundException

c# - 从 ASP.NET Core 1 迁移到 ASP.NET Core 2 后, token 身份验证停止工作

c# - TimeZone.IsInvalidTime 未捕获 2010 年埃及夏令时造成的无效时间

c# - CheckedListBox 选择所有项目 - Windows 窗体 C#

c# - 使用参数动态调用 dll 和方法