You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现带EventHandler的List<Form>作为MDI子窗体时遇赋值错误求助

问题分析与解决

错误根源

从堆栈信息可以明确:你在非UI线程中操作Windows Forms控件。最后一行的_StageTwoReaderServer是后台线程,事件从这里触发后,后续的窗体创建、MdiParent赋值等操作都在非UI线程执行,而WinForms要求所有UI控件的操作必须在创建它们的线程(即UI主线程)中进行,这才导致了Control.get_Handle()的报错——和你用不用List<T>存储窗体完全无关。

解决方案

通过Control.Invoke或BeginInvoke将UI操作切换到UI线程执行即可,不需要替换List<T>集合。

修改后的主窗体代码示例

假设你的JoinRoom方法是事件处理的入口,修改如下:

static List<frmWindow> Window = new List<frmWindow>();

private void JoinRoom(eventData e)
{
    // 判断当前是否在UI线程,不在则切换
    if (InvokeRequired)
    {
        Invoke(new Action<eventData>(JoinRoom), e);
        return;
    }

    // 以下代码在UI线程执行,安全操作窗体
    var newWindow = new frmWindow("windowName", 0);
    Window.Add(newWindow);
    newWindow.MdiParent = this;
    newWindow.Show();
}

额外说明

  • 之前非List<T>形式的代码正常,大概率是因为那些操作刚好在UI线程执行,没有触发跨线程场景。
  • 所有涉及UI控件的操作(包括窗体创建、属性赋值、显示)都必须放在UI线程,后续如果在frmWindow里有事件处理涉及UI更新,同样要检查InvokeRequired。

内容的提问来源于stack exchange,提问作者Josh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 17:03:11