Member 13871966 Ответов: 1

Как избежать "коллекция была изменена; операция перечисления может не выполняться." во время обновления диаграммы C#?


Всем привет,

Я столкнулся с этой проблемой, когда пытался использовать некоторое время и постоянно обновлять диаграмму.
Сначала я использую function: AddY() и function: removeAt() для обновления новейших данных, таких как пример 1.

Я также пытаюсь использовать массив для сохранения данных и самостоятельно сдвигать их влево, а также добавлять новые данные. После обновления массива я использую функцию: DataBindY() для рисования диаграммы. Пожалуйста, обратитесь к примеру 2.

Во время сборки ошибки нет, и функция сначала работает нормально, подождите случайное время, диаграмма превратится в Красный Крест и выскочит сообщение об ошибке, которое говорит: "коллекция была изменена; операция перечисления может не выполняться."

Есть две странные вещи: сборка успешна, это означает, что код правильный, не так ли? Во-вторых, это "случайное время", каждый раз, когда я пытаюсь выжить, время отличается. Это действительно не имеет смысла. Я искал это сообщение об ошибке в сети, но не смог найти знакомую ситуацию.

Может ли кто-нибудь, столкнувшийся с такой же ситуацией, помочь мне в этом?

Тнх.

Кстати, моя оконная система-Win7, а версия C# - 2010.

Что я уже пробовал:

Пример 1
bool fg_remove_chart_point = false;
uint counter = 0
while (true)
{
	Thread.sleep(1000);
	
	if (counter > 100)
  	    fg_remove_chart_point = true;
	
	if (fg_remove_chart_point)
	{
		chart_1.ChartAreas[0].AxisX.Minimum = 0;
		chart_1.ChartAreas[0].AxisX.Maximum = 100 + 2;
		
		chart_1.Series[0].Points.RemoveAt(0); //Delete
		chart_1.Update();
	}
	
	chart_1.Series[0].Points.AddY(50); //Draw chart
	chart_1.Update();	
	
	counter++;
}


Пример 2
double[] temperature = { };
bool fg_remove_chart_point = false;
uint counter = 0
while (true)
{
	Thread.sleep(1000);
	
	if (counter > 100)
  	    fg_remove_chart_point = true;
	
	if (fg_remove_chart_point)
	{
		chart_1.ChartAreas[0].AxisX.Minimum = 0;
		chart_1.ChartAreas[0].AxisX.Maximum = 100 + 2;
		
        //Update the array
		for (int x = 0; x < (100 - 1); x++)
			temperature[x] = temperature[x + 1];

		temperature[100 - 1] = Convert.ToDouble(50);
	}
	else
	{
		Array.Resize<double>(ref temperature, Convert.ToInt16(counter));
		temperature[counter - 1] = Convert.ToDouble(50);
	}
	
	chart_1.Series[0].Points.Clear();
	chart_1.Series[0].Points.DataBindY(temperature); //Use array to draw chart
	chart_1.Update();
	
	counter++;
}

Member 13871966

Всем Привет,

Я продолжаю гуглить и нахожу решение этой проблемы.
Он говорит, что если вы хотите изменить пользовательский интерфейс, то самый безопасный способ-использовать Invoke() или BeginInvoke().
После того как я использовал две функции вызова, чтобы позаботиться о добавлении и удалении точки, Красный крест больше никогда не показывался.

1 Ответов

Рейтинг:
1

User 7429338

Исключение "коллекция была изменена" означает, что один поток зацикливается на коллекции, которая в то же время изменяется в другом потоке.

Похоже, что вы изменяете данные диаграммы из фонового потока, что недопустимо.


Цитата:
сборка успешна, это означает, что код верен, не так ли?
Это совершенно определенно не так. Если сборка проходит успешно, это просто означает, что синтаксических ошибок нет. Он ничего не говорит о том, будет ли он делать то, что вы хотите; компилятор не может этого знать.