1

我试图从辅助线程隐藏在主线程上创建的表单,但是当我调用 hide 方法时,我显然遇到了跨线程问题。我是新手,对于如何纠正这个问题真的不知道。我总是创建一个委托来调用我的方法,如果它正在更改在主线程上创建的东西,但我不知道如何在这里为内置的 hide 方法执行此操作。如果您需要更多信息,请与我们联系。

代码:

public partial class MainForm : Form
{
    ControlPanelForm m_controlPanel = new ControlPanelForm();
    // ....
    void MeterThread()
    {
        while (true)
        {
            // ....
            if (EMOdetected)
            {
                m_controlPanel.Deinitialize();                    
                m_controlPanel.Hide();         // **** //
            }
        }
    }
}

基本上,我的 MainForm 会调出一个控制面板表单来完成一些工作。在后台我有一个线程正在运行并检查东西,其中一个是紧急关闭,此时我想关闭我的控制面板然后隐藏它。

如果我尝试在那里调用它,

m_controlPanel.Invoke(new EMOHandler(m_controlPanel.Hide));    // **** //

当我调试它时,它看起来不像执行任何东西。它似乎只是传递了命令。再说一次,我是新手,所以欢迎任何和所有的解释。

4

3 回答 3

5

没有理由检查InvokeRequired或创建匿名方法。简单地写

mainForm.Invoke(new MethodInvoker(mainForm.Hide));
于 2013-06-28T23:58:18.810 回答
2

您没有在代码方面提供任何信息,但这是从非 UI 线程操作 UI 线程的常见模式。

if (mainForm.InvokeRequired)
{
    mainForm.Invoke(new Action(() =>
    {
       mainForm.Hide();
    }));
}
else    
    mainForm.Hide();
于 2013-06-28T23:49:38.097 回答
0

作为一个简单的规则,您已经指出: 您不应该从另一个线程访问一个窗口。

我会建议你这样的事情:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        new Thread(SampleFunction).Start();
    }

    public void AppendTextBox(string value)
    {
        if (InvokeRequired)
        {
            this.Invoke(new Action<string>(AppendTextBox), new object[] {value});
            return;
        }
        textBox1.Text += value;
    }

    void SampleFunction()
    {
        // Gets executed on a seperate thread and 
        // doesn't block the UI while sleeping
        for(int i = 0; i<5; i++)
        {
            AppendTextBox("hi.  ");
            Thead.Sleep(1000);
        }
    }
}

这是我从这里得到的如何使用多线程的一个很好的例子。

尽管在您的情况下,该方法Hide已经存在于 MainForm 上,并且确实在等待您被调用,就像其他人已经指出的那样:

mainForm.Invoke(new MethodInvoker(mainForm.Hide));
于 2013-06-28T23:54:52.957 回答