";在创建窗口句柄之前,不能对控件调用Invoke或BeginInvoke;仅在第二次打开表单时发生

本文关键字:第二次 BeginInvoke 表单 Invoke 控件 窗口句柄 创建 quot 不能 调用 | 更新日期: 2023-09-27 18:22:11

我正在开发的应用程序是现有应用程序的插件,第一次运行插件时一切都很好。然而,当我第二次打开插件时,我得到了错误:

InvalidOperationException未处理-在创建窗口句柄之前,不能对控件调用Invoke或BeginInvoke

我了解竞争条件,从我所读到的内容来看,在HandleCreated为true之前尝试访问表单元素时会发生此错误,但我不明白为什么只有在第二次打开插件时才会发生这种情况。

这是插件代码。调用SetProgressBar():时出错

    private MainForm mainForm;
    public void StartPlugin()
    {
        mainForm  = new MainForm (this);
        mainForm .ShowDialog();
    }
    public bool GetJoinEnabled()
    {
        mainForm.SetProgressBar(3);
    }

这是我的主要表格:

    private Thread m_JoinThread;
    private JoinPlugin m_Join;
    public MainForm(JoinPlugin zig)
    {
        m_Join = zig;
        InitializeComponent();
        m_JoinThread= new Thread(new ThreadStart(GetJoinData));
        m_JoinThread.Start();
    }
    private void GetJoinData()
    {
       //Get enable join data
        bool result = m_Join.GetJoinEnabled();
    }
    public void SetProgressBar(int value)
    {
        SetProgressCallback del = new SetProgressCallback(SetProgressBarControl);
        this.Invoke(del, value);
    }
    private void SetProgressBarControl(int value)
    {
        progressBar.Value = value;
    }

";在创建窗口句柄之前,不能对控件调用Invoke或BeginInvoke;仅在第二次打开表单时发生

我有点猜测,但不久前我遇到了同样的问题。

您正在表单构造函数中启动一个线程:

m_JoinThread.Start();

这会立即启动线程,并在某个地方调用Invoke。此时,形式还没有完全初始化
将代码移动到Load事件:

public ZigbeeJoinForm_Load()
{
    m_JoinThread= new Thread(new ThreadStart(GetJoinData));
    m_JoinThread.Start();
}

这样可以确保表单完全初始化,并且调用Invoke是安全的。