Почему задание свойства enabled формы приводит к сбою приложения? - PullRequest
3 голосов
/ 03 июня 2010
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 Ответ

4 голосов
/ 03 июня 2010

Вы изменяете элемент управления winform в потоке, отличном от того, который создал этот элемент управления (основной поток пользовательского интерфейса). Элементы управления 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;
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...