集合已被修改,枚举操作可能无法执行。

3

好的,所以如果表单尚未打开,我希望打开一个新表单。因此,我根据表单的标题或文本检查表单是否存在。到目前为止,它可以工作,即表单会打开,如果它已经打开,它只是将其置于最前面。但我的问题是,如果它没有打开,并且我尝试创建一个新实例,它会抛出“集合已修改;可能无法执行枚举操作”的错误。我无论如何都想不出原因。感谢任何帮助。

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();
      }
   }
}
4个回答

7
不要使用 foreach,而是使用 for 循环:
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 Archer
@Dr_FeelGood:在循环中你根本没有使用iRow,所以我不知道你实际上想要实现什么。也许你需要另外提出一个问题,把foreachOpenForms的问题排除在外。 - Tim Schmelter
抱歉,应该是iRow而不是ChatReader(我忘记切换了,但无论如何它仍然创建了一个近1200的循环)。所以它给我一个相当大的循环而不是打开单个窗口。 - Dr Archer
谢谢@TimSchmelter,这确实解决了我的问题。我试图从列表(of T)中删除一个项目,但遇到了另一个问题。一旦删除后,退出循环就解决了所有问题。希望这也能帮助到其他人。 - Sikandar Amla
@SikandarAmla:如果您想要删除某些东西,请使用反向for循环:for (int i = Application.OpenForms.Count-1; i >= 0; i--)... 您还可以使用List.ForEach,它基本上是一个反向for循环的包装器,允许修改或甚至删除项目。 - Tim Schmelter

1
你可以在 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的解决方案中稍后打开。非常感谢! - Dr Archer

0
为什么不在循环遍历和修改字典时使用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; 

            }

这里有一篇关于它的文章:如何在C#中使用键迭代字典


0

真实的代码位于 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");
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接