1

I'm trying to hide a form created on the main thread, from a secondary thread but I obviously get a cross-threading issue when I call the hide method. I'm new to this and don't really have a clue as to how to how to correct this. I've always just created a delegate to invoke my method if it's changing stuff created on the main thread, but I don't know how to do that here for the built-in hide method. Let me know if you need more information.

code:

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

Basically, my MainForm pulls up a control panel form that does some work. In the background I have a thread running and checking for stuff, one of which is an Emergency Off, at which point I want to shut my control panel down and then hide it.

If I try to invoke it right there,

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

it doesn't look like it executes anything when i debug it. It seems to just pass over the command. Again, I'm new to this so any and all explanations are welcome.

Display Name
  • 83
  • 1
  • 6

3 Answers3

5

There's no reason to check InvokeRequired or create an anonymous method. Simply write

mainForm.Invoke(new MethodInvoker(mainForm.Hide));
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
2

You haven't given any information code-wise but this is a common pattern for manipulating the UI thread from a non-UI thread.

if (mainForm.InvokeRequired)
{
    mainForm.Invoke(new Action(() =>
    {
       mainForm.Hide();
    }));
}
else    
    mainForm.Hide();
keyboardP
  • 68,824
  • 13
  • 156
  • 205
0

As a simple rule, which you already pointed out: You should not access one window from another thread.

I would suggest you something like this:

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

This is a pretty nice example of how to use MultiThreading, which I got from here.

Though in your case, the method Hide already exists on MainForm and literally waits for you to be invoked, like others already pointed out:

mainForm.Invoke(new MethodInvoker(mainForm.Hide));
Community
  • 1
  • 1
Fabian Bigler
  • 10,403
  • 6
  • 47
  • 70