2011-02-09 60 views
2

嗨 我打开这样的形式从我的主窗体中,当用户选择一个菜单项。我只能关闭表单一次,InvalidOperation异常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(); 

我在我的应用程序中有多个线程,但它们是由我明确使用的控件创建的。 我通过一个委托[Marshall]接收/发送的数据将串行数据从/传递到表单。 它是有道理的,串行端口将运行在不同的线程上,而不是窗体,但为什么按钮单击表单是在一个不同的线程比形式?????

整个线程的事情是非常困惑 如何找出什么线程来自哪里,以及我没有明确创建的线程中发生了什么? 为什么我需要通过委托来调用窗体的close方法? 在这个线程安全的多线程环境中,有什么我可以做的事情我怎么知道我在做什么是不安全/安全的,如果我不知道什么/哪里/为什么/谁/什么时候创建线程?

+0

可能重复[我只能关闭窗体一次,InvalidOperation异常Invoke或BeginInvoke不能在控件上调用,直到窗口句柄被创建](http://stackoverflow.com/questions/4959502/i-can -only-close-a-form-once-invalidoperation-exception-invoke-or-begininvoke-ca) – 2011-02-10 20:36:57

回答

0

我的猜测是你的close()调用不是抛出这个异常,而是在close()之后发生的事情。你有没有用调试器加入代码来看它何时被触发?

至于何时需要调用......只有一个线程允许在GUI上进行更改和访问动态属性,称之为GUI线程。 GUI线程负责更新布局,触发按钮等事件。如果您从另一个线程(如计时器事件)访问GUI,则需要使用invoke()将您的函数排队以在GUI线程上运行。 BeginInvoke也会对函数进行排队,但是是异步的(只会排队要在GUI线程上运行的函数,但不会等待它完成)。

Close_button_click只有在按钮点击事件触发时才会由你的gui线程调用(除非你明确地在你的代码中的其他地方显式调用它,不推荐!),所以在你的代码中invokeRequired = false,并且调用代码永远不会执行。

+0

嗨SoggerI不得不安装VS 2010以获得加入代码的选项,但作为一个新手我过度了,但是什么是继续。我也在 – user593082 2011-02-10 15:36:11

相关问题