Why does setting a form's enabled property 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开发者_JAVA技巧 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 I quit the created process, my program crashes. Why?
You're modifying a winform control on a different thread than the one that created that control (the main UI thread). Winform controls are not thread-safe and typically will throw an exception if you modify their state from any thread other than the one that created it.
You can accomplish this using the InvokeRequired property and BeginInvoke method found on 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;
}
}
精彩评论