3

Does anyone know how I can change the window state of a form, from another thread? This is the code I'm using:

    private void button4_Click(object sender, EventArgs e)
    {
            string pathe = label1.Text;
            string name = Path.GetFileName(pathe);
            pathe = pathe.Replace(name, "");
            string runpath = label2.Text;
            Process process;
            process = new Process();

            process.EnableRaisingEvents = true;
            process.Exited += new System.EventHandler(process_Exited);

            process.StartInfo.FileName = @runpath;
            process.StartInfo.WorkingDirectory = @pathe;
            process.Start();
            WindowState = FormWindowState.Minimized;
    }
    private void process_Exited(object sender, EventArgs e)
    {
        this.WindowState = FormWindowState.Normal;
    }

It's meant to run a program and minimize, then return to the normal state once the program has closed. Although I get this error "Cross-thread operation not valid: Control 'Form1' accessed from a thread other than the thread it was created on." Any idea how to get this to work?

John Saunders
  • 157,405
  • 24
  • 229
  • 388
Joey Morani
  • 21,793
  • 29
  • 79
  • 126

5 Answers5

9

This will work in .NET 3.5:

Invoke(new Action(() => { this.WindowState = FormWindowState.Normal; }));

Or 2.0:

Invoke(new MethodInvoker(delegate { this.WindowState = FormWindowState.Normal; }));
Adam Robinson
  • 171,726
  • 31
  • 271
  • 330
1

Just search this string in StackOverflow "Cross-thread operation not valid" or Google. Please, don't be that lazy.

Andrey
  • 56,384
  • 10
  • 111
  • 154
1

See What’s the difference between Invoke() and BeginInvoke() on this site. The "chosen" answer gives a good explanation of what you're supposed to do.

Long story short, you want different THREADS not making a new process entirely (or highly unlikely you want that), and you probably want to use Invoke() and not BeginInvoke() which is asynchronous.

Community
  • 1
  • 1
Kevin Anderson
  • 5,815
  • 3
  • 29
  • 52
  • 1
    @Kevin: Considering he's starting an external application and waiting for it to exit, it seems like another process is *exactly* what he wants (in fact, requires). – Adam Robinson Apr 08 '10 at 16:35
1

Add this line of code to the Click event handler:

process.SynchronizingObject = this;
Hans Passant
  • 873,011
  • 131
  • 1,552
  • 2,371
-1

this will solve your problem add it in the form_load event

 System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
Roman C
  • 47,329
  • 33
  • 60
  • 147
  • 1
    This doesn't fix the problem, it *hides* the problem, by introducing race conditions into your code resulting in unexpected, unexplained, and inconsistent errors when running the code. As the program becomes more complex, the likelihood of problems, and the difficulty in either tracking them down or fixing the underlying problems, rises very quickly. This exception being thrown is a *feature*, and one that is very valuable. Disabling it is something you should virtually never be doing. – Servy Sep 10 '13 at 20:52