Why does setting a property allow the property to crash the application?

private void launchbutton_Click(object sender, EventArgs e)
    {
        launchbutton.Enabled = false;
        Process proc = new Process();
        proc.EnableRaisingEvents = true;
        proc.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
        //The arguments/filename is set here, just removed for privacy.
        proc.Exited += new EventHandler(procExit);
        proc.Start();
    }

    private void procExit(object sender, EventArgs e)
    {
        MessageBox.Show("YAY","WOOT");
        Thread.Sleep(2000);
        launchbutton.Enabled = true;
    }

2 seconds after the exit from the created process, my program will fail. Why?

+3
source share
1 answer

You are modifying a winform control in a different thread than the one that created this control (main user interface thread). Winform controls are not thread safe and usually throw an exception if you change your state from any thread other than the one that created it.

You can accomplish this using the InvokeRequired property and the BeginInvoke method found in the Form or control object.

For example, something like this:

    private void procExit(object sender, EventArgs e)
    {
        MessageBox.Show("YAY", "WOOT");
        Thread.Sleep(2000);
        // ProcessStatus is just a class I made up to demonstrate passing data back to the UI
        processComplete(new ProcessStatus { Success = true });
    }

    private void processComplete(ProcessStatus status)
    {
        if (this.InvokeRequired)
        {
            // We are in the wrong thread!  We need to use BeginInvoke in order to execute on the correct thread.
            // create a delegate pointing back to this same function, passing in the same data
            this.BeginInvoke(new Action<ProcessStatus>(this.processComplete), status);
        }
        else
        {
            // check status info
            if (status.Success)
            {
                // handle success, if applicable
            }
            else
            {
                // handle failure, if applicable
            }

            // this line of code is now safe to execute, because the BeginInvoke method ensured that the correct thread was used to execute this code.
            launchbutton.Enabled = true;
        }
    }
+4

Source: https://habr.com/ru/post/1748227/


All Articles