集合被修改枚举操作可能无法执行
Posted
技术标签:
【中文标题】集合被修改枚举操作可能无法执行【英文标题】: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();
【问题讨论】:
【参考方案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
。所以我不知道你实际上想要实现什么。也许您需要提出另一个问题,将foreach
和OpenForms
问题排除在外。
抱歉,它是 iRow 而不是 ChatReader(我忘了切换它,但不管怎样,它仍然会创建一个接近 1200 的循环)。所以它给了我一个相当大的循环而不是打开单个窗口。
感谢@TimSchmelter,这确实解决了我的问题。我试图从(T 的)列表中删除一个项目,但我遇到了另一个问题。 Exit For 一次删除解决了所有问题。希望这也可以帮助某人。
@SikandarAmla:如果你想删除一些东西,请使用向后的for
-loop:for (int i = Application.OpenForms.Count-1; i >= 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");
【讨论】:
以上是关于集合被修改枚举操作可能无法执行的主要内容,如果未能解决你的问题,请参考以下文章
System.invalidoperationexception:集合被修改;枚举操作可能无法在 .net 5 api 项目中执行