Коллекция была изменена, операция перечисления может не выполняться
Итак, я хочу открыть новую форму, если она еще не открыта. Поэтому я проверяю форму на основе заголовка или текста формы. Теперь, пока он работает, как в форме открывается, и если он уже открыт, он просто выводит его на передний план. Но моя проблема в том, что если он не открыт, и я пытаюсь создать его новый экземпляр, он выдает "Коллекция была изменена; операция перечисления может не выполняться". И я не могу на всю жизнь понять, почему. Любая помощь приветствуется.
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 ответа
Вы можете сохранить информацию в цикле 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();
...
}
Не используйте 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
во время перечисления. Но это произойдет, если вы создадите новую форму и покажете ее там. Вы добавляете другую форму в открытую коллекцию.
Код реальной жизни находится внутри MainForm
из WinForms
приложение.
/// <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");
}
Почему бы не использовать foraeach
при циклическом просмотре и изменении Dictionary
?? Мы можем перебрать словарь используя 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#