【问题标题】:collection was modified enumeration operation may not execute集合被修改枚举操作可能无法执行
【发布时间】:2013-09-29 21:30:51
【问题描述】:

好的,如果新表单尚未打开,我想打开它。所以我根据表单的标题或文本检查表单。现在,到目前为止它可以工作,因为表单打开了,如果它已经打开,它只是将它带到前面。但我的问题是,如果它没有打开,并且我尝试创建它的新实例,它会抛出“集合已修改;枚举操作可能无法执行”。而且我终其一生都无法弄清楚为什么。任何帮助表示赞赏。

foreach (DataRow iRow in chatcheck.Rows)
{
   FormCollection fc = Application.OpenForms;
   foreach (Form f in fc)
   {
      if (f.Text != ChatReader["Sender"].ToString())
      {

         ChatBox chat = new ChatBox();
         Connection.ConnectionStrings.chatopen = ChatReader["Sender"].ToString();
         chat.Text = Connection.ConnectionStrings.chatopen;
         chat.Show();
         chat.BringToFront();

      }
      else if (f.Text == ChatReader["Sender"].ToString())
      {
              f.BringToFront();
      }
   }
}

【问题讨论】:

    标签: c# foreach datatable sqldataadapter openform


    【解决方案1】:

    不要使用foreach,而是使用for-loop:

    for (int i = 0; i < Application.OpenForms.Count; i++ )
    {
        Form f = Application.OpenForms[i];
        if (f.Text != ChatReader["Sender"].ToString())
        {
    
            //...
            chat.Show();
            chat.BringToFront();
        }
        // ...
    }
    

    您无法在枚举期间更改 foreach 的基础集合。但是,如果您创建一个新表单并在那里显示它,就会发生这种情况。您将另一个表单添加到打开的集合中。

    【讨论】:

    • 谢谢你,它工作得很好......但现在它被封装在foreach(Datarow row in sometable.rows) 中,所以它创造了一个美妙的循环。但我需要那个 Datarow 循环来获取“发件人”信息。所以我不知道如何让它发挥作用。
    • @Dr_FeelGood:您在循环中根本没有使用iRow。所以我不知道你实际上想要实现什么。也许您需要提出另一个问题,将foreachOpenForms 问题排除在外。
    • 抱歉,它是 iRow 而不是 ChatReader(我忘了切换它,但不管怎样,它仍然会创建一个接近 1200 的循环)。所以它给了我一个相当大的循环而不是打开单个窗口。
    • 感谢@TimSchmelter,这确实解决了我的问题。我试图从(T 的)列表中删除一个项目,但我遇到了另一个问题。 Exit For 一次删除解决了所有问题。希望这也可以帮助某人。
    • @SikandarAmla:如果你想删除一些东西,请使用向后的for-loop:for (int i = Application.OpenForms.Count-1; i &gt;= 0; i--)... 你也可以使用List.ForEach,它基本上是一个向后for-loop 的包装器和允许修改甚至删除项目。
    【解决方案2】:

    您可以将信息保存在 foreach 循环中(例如,在 List 中),然后使用此信息打开表单。

                    var myList = new List<something>();
                    foreach (DataRow iRow in chatcheck.Rows)
                    {
                        FormCollection fc = Application.OpenForms;
                        foreach (Form f in fc)
                        {
                            if (f.Text != ChatReader["Sender"].ToString())
                            {
                               myList.Add(...)
                            }
                            else if (f.Text == ChatReader["Sender"].ToString())
                            {
                                f.BringToFront();
                            }
                        }
                    }
    

     

    foreach (var val in myList)
    {
       ChatBox chat = new ChatBox();
       ...
    }
    

    【讨论】:

    • 好的,谢谢你们俩。我让它工作。我必须通过formcollection检查表单是否打开,然后通过list.contains()检查它是否在列表中,如果它不是打开的表单或已经在列表中,则将其添加到列表中并打开后来在 Valery Petrov 的解决方案中。非常感谢!
    【解决方案3】:

    为什么在循环和修改Dictionary 时不使用foraeach? 我们可以使用foreach 遍历字典,其键如下:

                //get key collection from dictionary into a list to loop through    
                List<int> keys = new List<int>(Dictionary.Keys);
    
                // iterating key collection using simple for-each loop
                foreach (int key in keys)
                { 
                    // Now we can perform any modification with values of dictionary.    
                    Dictionary[key] = Dictionary[key] - 1; 
    
                }
    

    这是一篇关于它的帖子:How To Iterate a Dictionary Using Keys In C#

    【讨论】:

      【解决方案4】:

      真实代码位于WinForms 应用程序的MainForm 内。

          /// <summary>
          /// Creates and connects the hub connection and hub proxy. 
          /// </summary>
          private async void ConnectWithRetryAsync()
          {
              Connection = new HubConnection(Properties.Settings.Default.ServerBaseUrl);
              Connection.Closed += Connection_Closed;
              Connection.Error += Connection_Error;
              HubProxy = Connection.CreateHubProxy("signalcalendar");
      
              //Handle incoming event from server: use Invoke to write to log from SignalR's thread
              HubProxy.On<CalendarUpdateRequest>("UpdateCalendarEvent", (calendarUpdateRequest) =>
                  this.Invoke((Action)(() =>
                  {
                      try
                      {
                          if (calendarUpdateRequest == null) return;
      
                          // Reject my own calendar's changes
                          if (calendarUpdateRequest.UserInfo.UserId == Program.UserInfo.UserId) return;
      
                          //Notify all opened Form about Calendar changes
                          for (int i = 0; i < Application.OpenForms.Count; i++)
                          {
                              var openForm = Application.OpenForms[i];
      
                              try
                              {
                                  var currentFormType = openForm.GetType();
                                  if (currentFormType == typeof(CommonForm))
                                  {
                                      if ((openForm as CommonForm).AppWindowType == AppWindowTypes.FactTruckForm ||
                                          (openForm as CommonForm).AppWindowType == AppWindowTypes.PlanTruckForm ||
                                          (openForm as CommonForm).AppWindowType == AppWindowTypes.FactExcForm ||
                                          (openForm as CommonForm).AppWindowType == AppWindowTypes.PlanExcForm)
                                      {
                                          (openForm as CommonForm).CalendarHasBeenChanged(calendarUpdateRequest);
                                      }
                                  }
                              }
                              catch (Exception ex)
                              {
                                  logger.Error(ex);
                              }
                          }
                      }
                      catch (Exception ex)
                      {
                          logger.Error(ex);
                      }
                  }
                  ))
              );
      
              #region  Connect to the Server
              try
              {
                  await Connection.Start();
              }
              catch (HttpRequestException ex)
              {
                  var errorMessage = "There is no connection with Server. Check your netwrok and Server App state";
                  logger.Error(errorMessage);
                  logger.Error(ex);
      
                  MetroMessageBox.Show(this, errorMessage, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
      
                  Close();
              }
      
              #endregion
      
              //Activate UI          
              logger.Info("COnnection has been established OK");
          }
      

      【讨论】:

        猜你喜欢
        • 2012-04-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-17
        相关资源
        最近更新 更多