【问题标题】:C# System.InvalidOperationException: Collection was modified; enumeration operation may not executeC# System.InvalidOperationException:集合已修改;枚举操作可能无法执行
【发布时间】:2011-10-05 13:57:00
【问题描述】:

我已经研究过这个问题,但还没有找到适合我的问题。我不是想编辑我正在循环的东西。

************** Exception Text **************
System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
at System.Collections.Generic.List`1.Enumerator.MoveNextRare()
at System.Collections.Generic.List`1.Enumerator.MoveNext()

这是我的函数导致它:

internal static bool CloseAllForms()
{
    try
    {
        if (clsGlobal.g_objfrmCustomerInformation != null)
            clsGlobal.g_objfrmCustomerInformation.Close();
        if (clsGlobal.g_objfrmSearchCustomer != null)
            clsGlobal.g_objfrmSearchCustomer.Close();

        if (clsGlobal.g_objfrmSwipeLicense != null)
            clsGlobal.g_objfrmSwipeLicense.Close();

        if (clsGlobal.g_objfrmSearchResults != null)
            clsGlobal.g_objfrmSearchResults.Close();

        if (clsGlobal.g_objfrmCustomerData != null)
            clsGlobal.g_objfrmCustomerData.Close();
        if (clsGlobal.g_objfrmPurchaseOrder != null)
            clsGlobal.g_objfrmPurchaseOrder.Close();
        if (clsGlobal.g_objfrmAddPurchaseOrderItem != null)
            clsGlobal.g_objfrmAddPurchaseOrderItem.Close();
        if ((clsGlobal.g_objfrmCustomerInformation == null) && (clsGlobal.g_objfrmSearchCustomer == null) && (clsGlobal.g_objfrmSwipeLicense == null) && (clsGlobal.g_objfrmSearchResults == null) && (clsGlobal.g_objfrmCustomerData == null) && (clsGlobal.g_objfrmPurchaseOrder == null) && (clsGlobal.g_objfrmAddPurchaseOrderItem == null))
        {
            PrepareImageBar();
            return true;
        }
        else
        {
            PrepareImageBar();
            return false;
        }
    }
    catch (Exception ex)
    {
        string ErrorMessage;

        ErrorMessage = "Error: " + ex.Message +
           "\r\nSource: " + ex.Source +
           "\r\nTargetSite: " + ex.TargetSite.ToString() +
           "\r\nStackTrace: " + ex.StackTrace.ToString();

        if (ex.Data.Count > 0)
        {
            ErrorMessage += "\r\nData Count: " + ex.Data.Count.ToString() +
                "\r\nKeys: " + ex.Data.Keys.ToString() +
                "\r\nValues: " + ex.Data.Values.ToString();
        }

        MessageBox.Show(ErrorMessage, "", MessageBoxButtons.OK, MessageBoxIcon.Error);
        CustomFunctions.emailExceptionToAuthor(ex);

        return false;
    }
}

这就是我调用函数的方式:

if (CloseAllForms())
{
    if (clsGlobal.g_objfrmPurchaseOrder == null)
    {
        clsGlobal.g_objfrmPurchaseOrder = new frmPurchaseOrder();

        clsGlobal.g_objfrmPurchaseOrder.FormClosed += PurchaseOrderFormClosed;
        clsGlobal.g_objfrmPurchaseOrder.MdiParent = clsGlobal.g_objfrmMDIMain;
        clsGlobal.g_objfrmPurchaseOrder.Show();
        clsGlobal.g_objfrmPurchaseOrder.BringToFront();
    }
    else
    {
        clsGlobal.g_objfrmPurchaseOrder.Show();
        clsGlobal.g_objfrmPurchaseOrder.BringToFront();
    }

    PrepareImageBar();
}

请帮帮我!

更新:这是完整的代码。

例外 有关调用的详细信息,请参阅此消息的末尾 即时 (JIT) 调试,而不是此对话框。

************** Exception Text **************
System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
at System.Collections.Generic.List`1.Enumerator.MoveNextRare()
at System.Collections.Generic.List`1.Enumerator.MoveNext()
at Microsoft.VisualBasic.PowerPacks.ShapeCollection.Dispose(Boolean disposing)
at Microsoft.VisualBasic.PowerPacks.ShapeContainer.Dispose(Boolean disposing)
at System.ComponentModel.Component.Dispose()
at System.Windows.Forms.Control.Dispose(Boolean disposing)
at System.Windows.Forms.Form.Dispose(Boolean disposing)
at B2HD_Software.frmCustomerData.Dispose(Boolean disposing)
at System.Windows.Forms.Form.WmClose(Message& m)
at System.Windows.Forms.Form.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

PrepareImageBar();

internal static void PrepareImageBar()
{
clsGlobal.g_objfrmMDIMain.mnuImageBarAddCustomer.Visible = false;
clsGlobal.g_objfrmMDIMain.mnuImageBarAddCustomer.Enabled = true;
clsGlobal.g_objfrmMDIMain.mnuImageBarEditCustomer.Visible = false;
clsGlobal.g_objfrmMDIMain.mnuImageBarEditCustomer.Enabled = true;
clsGlobal.g_objfrmMDIMain.mnuImageBarFindCustomer.Visible = false;
clsGlobal.g_objfrmMDIMain.mnuImageBarFindCustomer.Enabled = true;
clsGlobal.g_objfrmMDIMain.mnuImageBarStartSearch.Visible = false;
clsGlobal.g_objfrmMDIMain.mnuImageBarStartSearch.Enabled = false;
clsGlobal.g_objfrmMDIMain.mnuImageBarSwipeLicense.Visible = false;
clsGlobal.g_objfrmMDIMain.mnuImageBarSwipeLicense.Enabled = true;
clsGlobal.g_objfrmMDIMain.mnuImageBarViewNotes.Visible = false;
clsGlobal.g_objfrmMDIMain.mnuImageBarViewNotes.Enabled = true;
clsGlobal.g_objfrmMDIMain.mnuImageBarNewPurchase.Visible = false;
clsGlobal.g_objfrmMDIMain.mnuImageBarNewPurchase.Enabled = true;
clsGlobal.g_objfrmMDIMain.mnuImageBarAddItem.Visible = false;
clsGlobal.g_objfrmMDIMain.mnuImageBarAddItem.Enabled = true;
clsGlobal.g_objfrmMDIMain.mnuImageBarModifyItem.Visible = false;
clsGlobal.g_objfrmMDIMain.mnuImageBarModifyItem.Enabled = false;
clsGlobal.g_objfrmMDIMain.mnuImageBarDeleteItem.Visible = false;
clsGlobal.g_objfrmMDIMain.mnuImageBarDeleteItem.Enabled = false;
clsGlobal.g_objfrmMDIMain.mnuImageBarTakePicture.Visible = false;
clsGlobal.g_objfrmMDIMain.mnuImageBarTakePicture.Enabled = true;
clsGlobal.g_objfrmMDIMain.mnuImageBarSavePicture.Visible = false;
clsGlobal.g_objfrmMDIMain.mnuImageBarSavePicture.Enabled = true;
clsGlobal.g_objfrmMDIMain.mnuImageBarSave.Visible = false;
clsGlobal.g_objfrmMDIMain.mnuImageBarSave.Enabled = true;
clsGlobal.g_objfrmMDIMain.mnuImageBarCancel.Visible = false;
clsGlobal.g_objfrmMDIMain.mnuImageBarCancel.Enabled = true;
clsGlobal.g_objfrmMDIMain.mnuImageBarAdmin.Visible = false;
clsGlobal.g_objfrmMDIMain.mnuImageBarAdmin.Enabled = true;

switch (clsGlobal.ActiveForm())
{
    case "CustomerInformation":
        clsGlobal.g_objfrmMDIMain.mnuImageBarTakePicture.Visible = true;
        clsGlobal.g_objfrmMDIMain.mnuImageBarSave.Visible = true;
        clsGlobal.g_objfrmMDIMain.mnuImageBarCancel.Visible = true;
        clsGlobal.g_objfrmMDIMain.mnuImageBarCancel.Enabled = true;

        break;
    case "SearchCustomer":
        clsGlobal.g_objfrmMDIMain.mnuImageBarStartSearch.Visible = true;
        clsGlobal.g_objfrmMDIMain.mnuImageBarSwipeLicense.Visible = true;
        clsGlobal.g_objfrmMDIMain.mnuImageBarCancel.Visible = true;
        clsGlobal.g_objfrmMDIMain.mnuImageBarStartSearch.Enabled = false;

        break;
    case "SwipeLicense":
        clsGlobal.g_objfrmMDIMain.mnuImageBarCancel.Visible = true;

        break;
    case "CustomerData":
        clsGlobal.g_objfrmMDIMain.mnuImageBarCancel.Visible = true;
        clsGlobal.g_objfrmMDIMain.mnuImageBarViewNotes.Visible = true;
        clsGlobal.g_objfrmMDIMain.mnuImageBarNewPurchase.Visible = true;
        clsGlobal.g_objfrmMDIMain.mnuImageBarEditCustomer.Visible = true;

        break;
    case "PurchaseOrder":
        clsGlobal.g_objfrmMDIMain.mnuImageBarCancel.Visible = true;
        clsGlobal.g_objfrmMDIMain.mnuImageBarAddItem.Visible = true;
        clsGlobal.g_objfrmMDIMain.mnuImageBarDeleteItem.Visible = true;
        clsGlobal.g_objfrmMDIMain.mnuImageBarModifyItem.Visible = true;
        clsGlobal.g_objfrmMDIMain.mnuImageBarEditCustomer.Visible = true;
        clsGlobal.g_objfrmMDIMain.mnuImageBarViewNotes.Visible = true;

        clsGlobal.g_objfrmPurchaseOrder.ShowProperButtons();

        break;
    case "AddPurchaseOrderItem":
        clsGlobal.g_objfrmMDIMain.mnuImageBarTakePicture.Visible = true;
        clsGlobal.g_objfrmMDIMain.mnuImageBarSave.Visible = true;
        clsGlobal.g_objfrmMDIMain.mnuImageBarCancel.Visible = true;
        clsGlobal.g_objfrmMDIMain.mnuImageBarViewNotes.Visible = true;

        break;

    default:
        clsGlobal.g_objfrmMDIMain.mnuImageBarAddCustomer.Visible = true;
        clsGlobal.g_objfrmMDIMain.mnuImageBarFindCustomer.Visible = true;
        clsGlobal.g_objfrmMDIMain.mnuImageBarSwipeLicense.Visible = true;

        break;
}
}

CloseAllForms()

internal static bool CloseAllForms()
{
if (clsGlobal.g_objfrmCustomerInformation != null)
    clsGlobal.g_objfrmCustomerInformation.Close();

if (clsGlobal.g_objfrmSearchCustomer != null)
    clsGlobal.g_objfrmSearchCustomer.Close();

if (clsGlobal.g_objfrmSwipeLicense != null)
    clsGlobal.g_objfrmSwipeLicense.Close();

if (clsGlobal.g_objfrmSearchResults != null)
    clsGlobal.g_objfrmSearchResults.Close();

if (clsGlobal.g_objfrmCustomerData != null)
    clsGlobal.g_objfrmCustomerData.Close();

if (clsGlobal.g_objfrmPurchaseOrder != null)
    clsGlobal.g_objfrmPurchaseOrder.Close();

if (clsGlobal.g_objfrmAddPurchaseOrderItem != null)
    clsGlobal.g_objfrmAddPurchaseOrderItem.Close();

if ((clsGlobal.g_objfrmCustomerInformation == null) && (clsGlobal.g_objfrmSearchCustomer == null) && (clsGlobal.g_objfrmSwipeLicense == null) && (clsGlobal.g_objfrmSearchResults == null) && (clsGlobal.g_objfrmCustomerData == null) && (clsGlobal.g_objfrmPurchaseOrder == null) && (clsGlobal.g_objfrmAddPurchaseOrderItem == null))
{
    PrepareImageBar();
    return true;
}
else
{
    PrepareImageBar();
    return false;
}

}

这就是我的关闭事件在每个表单上的样子。

internal static void CustomerInformationFormClosed(object sender, FormClosedEventArgs e)
    {
        clsGlobal.g_objfrmCustomerInformation = null;

        PrepareImageBar();
    }

【问题讨论】:

  • 你能提供完整的堆栈跟踪吗?你知道代码失败的地方吗(也许是PrepareImageBar 中的东西?
  • 什么平台? (asp?silverlight?wpf?控制台?等)
  • 这里缺少一些代码;可能是在列表上有一个foreach 循环,而在foreach 循环中的某个位置,您正尝试在集合中添加或删除一个项目。
  • +1 on @vcsjones 评论,很可能您正在修改集合,同时在同一线程或不同线程上循环遍历它。
  • 去掉try and catch,它会阻止你看到代码真正炸弹的地方。别管它。请改用 AppDomain.UnhandledException。

标签: c# invalidoperationexception


【解决方案1】:

我看到了三种可能性:

  1. 其中一种表单的 FormClosed 事件处理程序出现故障(即,可能在 PurchaseOrderFormClosed 中出现问题)。
  2. 您的CloseAllForms() 方法在catch 中做了大量工作。代码可能在那里失败。当错误发生时,你看到MessageBox了吗?电子邮件是否发送?尝试注释掉那里的所有代码,看看是否仍然出现错误。或者只是暂时将catch 中的所有代码替换为MessageBox.Show(ex.ToString()),这样您就可以确定您看到的异常发生在try 中。
  3. PrepareImageBar() 出现故障。尝试注释掉该方法,看看是否仍然出现错误。

【讨论】:

  • 我实际上只是把所有这些东西都放在了捕获中,因为我试图想出一种方法让它给我任何有用的东西。我没有收到消息框。我刚刚用所有可能失败的方法的完整代码更新了我的问题。
  • 从您的堆栈跟踪来看,尝试关闭 frmCustomerData 时似乎失败了。该表单的CloseDispose 方法中是否发生了任何事情?如果您没有收到消息框,我会怀疑异常发生在单独的线程上,因此可能会在您的应用程序启动时为 AppDomain.UnhandledException 事件连接一个处理程序(如您的问题的 cmets 中所建议的那样)。
  • 我更新了上面的代码以显示 Closed 事件。我不知道如何在没有为每个表单设置全局变量的情况下从另一个表单访问一个表单......所以当表单关闭时,它会将变量设置为空......有更好的方法吗?
  • 如果你跳过关闭frmCustomerData,你仍然得到错误吗?也许它与 PowerPacks 有关。
  • 谢谢!!!!!!这是我使用 VB 电源组绘制的几条愚蠢的线条。如果我摆脱它们,错误就会消失。处置它们一定是个问题。我将手动绘制它们。感谢您解决了这 4 天的头痛问题!
【解决方案2】:

我不知道异常发生在哪里,但异常可能是在修改集合的foreach 代码块中生成的。在这里,修改的意思是“添加”或“删除”,例如:

foreach(var item in collection)    { collection.Add(other);}

枚举时不能修改集合。


更新

若要在您的代码中查找它发生的位置,请在调试时检查“异常”对话框中的“用户未处理选项”(Ctrl+Alt+E)。但是请注意,要使用此选项,VS 必须在调试选项中设置“仅启用我的代码”。

【讨论】:

  • 我已将范围缩小到我发布的功能。如果我没有在我的事件中运行我的代码的 if (CloseAllForms()) 部分,则不会引发异常。我已经尝试了所有可能的方法来捕获异常并处理它,但它仍然会引发未处理的异常。您说启用的选项也已启用。我找不到“只是我的代码”选项,但调试非托管代码被禁用我认为这就是你想要的?我无法弄清楚这一点,因为据我所知,我没有更改收藏。
  • 我明白了。仅使用您发布的代码进行测试会很困难。 VS 在你的源代码中停止了这个异常?
  • 就是这样(不过我忘了提)。当我在安装了VS的计算机上测试它时,调试与否......没有错误。当我将它部署在另一个工作站上时,它会出错。不给我一行代码或任何东西。我只知道经过反复试验,如果我不运行 CloseAllForms() 它不会出错。有没有更好的方法来确保我可以尝试关闭所有 MDI 子项?
  • 我知道这正是你的问题。我猜这将是孩子处置的结果,但还不知道具体情况。如果找到善良,我会告诉你......
【解决方案3】:

我看到了这个错误: 该错误显然只出现在某些 Windows 安装上,而且我从来没有通过调试在开发环境中出现过,只有完整的应用程序才会出现。

这是 VisualBasic.PowerPacks 中的一个错误。

See here for a solution(见博客末尾)。

您基本上必须重写表单的 Dispose() 方法并手动处理所有 VisualBasic Powerpack 项目。

【讨论】:

    猜你喜欢
    • 2020-02-07
    • 2022-06-17
    • 1970-01-01
    • 2015-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-24
    相关资源
    最近更新 更多