Я могу закрыть форму только один раз, InvalidOperation Exception Invoke или BeginInvoke нельзя вызвать для элемента управления, пока не будет создан дескриптор окна

Привет, я открываю такую ​​​​форму из своей основной формы, когда пользователь выбирает пункт меню.

private void commToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Command_Form Command_Form1 = new Command_Form();
            Command_Form1.ShowDialog();
           // Command_Form1.Dispose();    this didn't help
        }

Внутри формы «Command_Form1» я закрываю ее вот так, когда пользователь нажимает кнопку закрытия

private void Close_button_Click(object sender, EventArgs e)
        {
          this.Close();    //I get the exception here 
        }

Этот процесс отлично работает один раз, но при втором закрытии формы (надеюсь, это совершенно другой/новый экземпляр формы) я получаю сообщение об ошибке в заголовке этого сообщения. Это вывод в окне отладки.

Первое исключение типа System.InvalidOperationException в System.Windows.Forms.dll

Во всех темах, в которых указана эта ошибка, говорится о том, что я не пытаюсь ничего сделать с формой, которая не отображается, но это происходит, когда я нажимаю кнопку в форме. Мне кажется, что в значительной степени гарантирует, что форма была отображена, если я могу щелкнуть ее кнопку.

Другие сообщения, которые я нашел, в которых перечислены ошибки этого типа, касаются выполнения потокобезопасных вызовов, поэтому я попробовал это в качестве эксперимента, но это не имело никакого значения.

private void Close_button_Click(object sender, EventArgs e)
            {
    if (this.InvokeRequired)
                {
                    CloseCallback d = new CloseCallback(Close_button_Click);
                    Invoke(d, new object[] { sender, e });
                }
                else
                {
                    this.Close();

У меня есть несколько потоков в моем приложении, но они создаются элементами управления, которые я использую, а не мной явно. Я передаю данные из последовательного порта в/из формы путем маршалинга полученных/отправленных данных через делегата[ов]. Имеет смысл, что последовательный порт будет работать в потоке, отличном от формы, но почему нажатие кнопки на форме должно быть в потоке, отличном от формы????

Весь этот поток очень сбивает с толку. Как мне выяснить, какие потоки возникли, где и что происходит в потоках, которые я не создавал явно? Зачем мне вызывать метод закрытия формы через делегат? Черт возьми, есть ли что-нибудь, что я могу сделать в этой многопоточной среде, которая является потокобезопасной. Как я узнаю, что то, что я делаю, небезопасно/безопасно, если я не знаю, что/где/почему/кто/когда создает потоки?


person user593082    schedule 09.02.2011    source источник


Ответы (1)


Я предполагаю, что ваш вызов close() не генерирует это исключение, а что-то, что происходит после close(). Вы вошли в код с помощью отладчика, чтобы увидеть, когда он запускается?

Что касается того, когда вам нужно вызывать... Существует только один поток, которому разрешено вносить изменения и получать доступ к динамическим свойствам в графическом интерфейсе, назовите его потоком графического интерфейса. Поток графического интерфейса отвечает за обновление макета, запуск событий, таких как кнопки и т. д. Если вы когда-либо обращаетесь к графическому интерфейсу из другого потока (например, из события таймера), вам нужно использовать invoke() для постановки вашей функции в очередь для запуска в потоке графического интерфейса. BeginInvoke также поставит функцию в очередь, но будет асинхронной (только поставит в очередь функцию, которая должна быть запущена в потоке графического интерфейса, но не будет ждать ее завершения).

Close_button_click будет вызываться вашим потоком графического интерфейса только тогда, когда срабатывает событие нажатия кнопки (если вы явно не вызываете его где-то еще в своем коде, что не рекомендуется!), поэтому invokeRequired=false в вашем коде выше, и код вызова никогда не выполняется.

person Sogger    schedule 09.02.2011
comment
Привет, Соггер. Мне пришлось установить VS 2010, чтобы получить возможность перейти к коду, но, как новичок, я поражен, но что происходит. Я также по предложению - person user593082; 10.02.2011
comment
другие я удалил последовательный порт из формы и сделал его глобальным. это все еще не решает проблему. Я снова опубликую вопрос и надеюсь, что не оскорблю их снова, не попробовав первые предложенные предложения. Я не хотел никого обидеть, я просто спросил, почему все происходит. Я не был против реструктуризации моей программы. Я хотел понять, почему я вижу то, что вижу. - person user593082; 10.02.2011
comment
Репост не является хорошей идеей, чтобы получить лучшую обратную связь. Вы получите лучшую обратную связь, если будете задавать более короткие, лаконичные и лучше объясненные вопросы, которые положат начало разговору для получения решений. - person Sogger; 10.02.2011
comment
Репост решил мою проблему. вот ссылка -begininvoke-ca" title="я могу закрыть форму только после вызова исключения недействительной операции или begininvoke ca"> stackoverflow.com/questions/4959502/ - person user593082; 11.02.2011
comment
Репост решил мою проблему. Я извиняюсь за нарушение протокола, но ответ, в котором предлагалось полностью реструктурировать мою программу, чтобы устранить проблему, не понимая, в первую очередь, ее причину, не помог мне чему-либо научиться. Вот ссылка на решение stackoverflow.com/questions/4959502/ - person user593082; 11.02.2011