为什么设置表单的启用属性会使应用程序崩溃?

时间:2010-06-02 20:05:41

标签: c# forms process crash

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秒钟,我的程序崩溃了。为什么呢?

1 个答案:

答案 0 :(得分:4)

您正在修改与创建该控件的线程不同的线程上的winform控件(主UI线程)。 Winform控件不是线程安全的,如果你从创建它的线程以外的任何线程修改它们的状态,通常会抛出异常。

您可以使用在窗体或控件对象上找到的InvokeRequired属性和BeginInvoke方法来完成此操作。

例如,像这样:

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