【发布时间】:2016-03-28 01:42:22
【问题描述】:
谁能告诉我为什么 exitToolStripMenuItem_Click 会引发 InvalidOperationException。我知道这是由于调用了 plugin.Close() 而发生的。但是,我不明白为什么。通过“X”按钮关闭 Form1 不会触发异常。调用 Application.Exit() 确实如此。下面是一个示例,用于演示我的主应用程序中发生的事情。在我的主应用程序中,某些表单关闭会触发事件,因此我需要确保在每个表单上都调用 Close。我可以将 Application.Exit() 更改为 Close() 但是在阅读 MSDN 之后,我觉得这不是正确的解决方案。任何想法都会有所帮助,谢谢。
注意:我正在开发的主要应用程序是多线程的。
public partial class Form1 : Form
{
Form plugin = new Form();
public Form1()
{
InitializeComponent();
plugin.Show();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
plugin.Close();
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
抛出的异常是:
Exception thrown: 'System.InvalidOperationException' in mscorlib.dll
System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
at System.Collections.ArrayList.ArrayListEnumeratorSimple.MoveNext()
at System.Windows.Forms.Application.ExitInternal()
at System.Windows.Forms.Application.Exit(CancelEventArgs e)
at System.Windows.Forms.Application.Exit()
at WindowsFormsApplication2.Form1.exitToolStripMenuItem_Click(Object sender, EventArgs e)
【问题讨论】:
-
不要调用Application.Exit,使用适当的关闭表单(IE关闭)
-
这是因为您试图在它的关闭事件中关闭表单。当您到达 FormClosing 事件方法时,Application.Exit() 已经对表单提出了关闭请求。无需在 FormClosing 上调用 Close。
-
我将表单的名称更改为 plugin 以减少混淆。我的主窗体需要在退出之前关闭所有插件。插件可能处于某种状态,不会被闲置以杀死。据我了解 Application.Exit 是在多线程应用程序中调用的正确方法。如果这不是真的,有人可以指出我的 msdn 声明或另一篇文章,解释为什么我会使用 Close 而不是 Application.Exit。
-
@HenkHolterman 抱歉,我试图让代码示例保持简单,但可能会影响响应。
-
当我说多线程时,我并不是说插件在它们自己的 UI 线程上运行。它们都在主应用程序线程上实例化。但是,每个表单都可能在后台线程上运行某些东西。每个插件在关闭时都会处理自己的清理工作。我相信这个问题仍然完全有效。上面的代码抛出异常。基于 msdn Application.Exit() 似乎是正确的调用方法,我错了吗?
标签: c# winforms invalidoperationexception