I can only close a form once, InvalidOperation Exception Invoke or BeginInvoke cannot be called on a control until the window handle has been created

你说的曾经没有我的故事 提交于 2020-01-04 05:41:11

问题


Hi I'm opening a form like this from my main form when the user makes a selection of a menu item.

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
        }

Inside the form "Command_Form1" I close it like this when the user clicks on the close button

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

This process works fine once but on the second closing of the form (Which I hope is a completely different/new instance of the form) I get the error in the title of this post. This is the output in the debug window.

A first chance exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll

All the topics that list this error go on about not trying to do anything to a form that has not been displayed but this happens when I click on a button in the form. It would seem to me that pretty much ensures the form has been displayed if I'm able to click its button.

The other posts I've found that list this type of error go on about making thread safe calls so I tried this as an experiment but it didn't make any difference.

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();

I have multiple threads in my application but they are created by the controls I'm using not by me explicitly. I am passing data from a serial port to/from the form by Marshling the received/sent data via a delegate[s]. It makes sense that the serial port would run on a different thread than the form but why would a button click on a form be in a diffrent thread than the form????

The whole thread thing is very confuzing How do I figure out what threads originated where and what is going on in the threads that I didn't create explicitly? Why would I need to invoke the form's close method via a delegate? Heck is there anything I can do in this multi threading environment that is thread safe How in do I know if what I'm doing is unsafe/safe if I don't know what/where/why/who/when is creating threads?


回答1:


My guess is your close() call is not throwing that exception, but something that happens after close(). Have you stepped into the code with the debugger to see when it is fired?

As to when you need to invoke...There is only one thread allowed to make changes and access dynamic properties on the GUI, call it the GUI thread. The GUI thread is responsible for updating layout, firing events like buttons, etc. If you ever access the GUI from another thread (like a timer event) you need to use invoke() to queue your function to be run on the GUI thread. BeginInvoke will also queue the function but is asynchronous (will only queue the function to be run on GUI thread, but will not wait for it to finish).

Close_button_click will only be called by your gui thread when the button click event fires(unless you explicitly call it somewhere else in your code behind, not recommended!), so invokeRequired=false in your code above, and the invoke code is never executed.



来源:https://stackoverflow.com/questions/4948087/i-can-only-close-a-form-once-invalidoperation-exception-invoke-or-begininvoke-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!