-Коллекция была изменена; операция перечисления может не выполняться - PullRequest
0 голосов
/ 30 марта 2020

Непрерывные данные поступают из последовательного порта. Я передаю данные из последовательного порта в таблицу c # ms. но я сталкиваюсь с этой ошибкой. Я посмотрел на несколько решений, но не смог понять.

коды

    ConcurrentQueue<string> kuyruk = new ConcurrentQueue<string>();
    string result;

    private void addPoint()
    {
        string pnt;
        while (true)
        {
            if (!kuyruk.IsEmpty)
            {
                if (kuyruk.TryDequeue(out pnt))
                    chart1.Series[0].Points.AddY(pnt);
            }
        }
    }

    private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
            var indata = serialPort1.ReadChar();
            if (indata != 13 && indata != 10)
                result += Convert.ToChar(indata);
            else
            {
                if (result != null)
                    kuyruk.Enqueue(result.ToString());
                result = null;
            }

    }

    private void button1_Click(object sender, EventArgs e)
    {
        serialPort1.PortName = "COM3";
        serialPort1.BaudRate = 9600;
        serialPort1.Open();

        Thread thread = new Thread(new ThreadStart(addPoint));
        thread.Start();
    }

ошибка

enter image description here

подробности

enter image description here

Ответы [ 3 ]

1 голос
/ 30 марта 2020

Хорошо, вот как это сделать (безопасно).

Root причина:

Вы управляете коллекцией из фонового потока, который одновременно проходит через компонентом формы в главном потоке (UI).

Решение:

Чтобы безопасно добавить в коллекцию, вы должны сделать это в главном потоке. Windows Фреймворк форм предоставляет способы для достижения этой цели. Один из них следующий:

Подход, реализованный здесь, был проверен и доказал свою эффективность. (Точки, добавленные фоновым потоком, были успешно обработаны компонентом диаграммы)

Добавьте делегата, принимающего строковый параметр, в класс формы:

public delegate void OnSerialDataReceived(string pnt);

Добавьте метод, принимающий строковый параметр в вашем классе формы. Этот метод будет использоваться в качестве конкретной реализации делегата.

    private void AddPointToChart(string pnt)
    {
        chart1.Series[0].Points.AddY(pnt);
    }

Когда вы удаляете новые данные из вашей параллельной очереди, вместо добавления точки выполните следующее:

    private void addPoint()
    {
        string pnt;
        while (true)
        {
            if (!kuyruk.IsEmpty)
            {
                if (kuyruk.TryDequeue(out pnt))
                {
                    // This will guarantee safe invocation of the target method
                    // on the UI thread
                    var safeInvoker = new OnSerialDataReceived(AddPointToChart);
                    chart1.Invoke(safeInvoker, pnt);
                }
            }
        }
    }

Это все.

Удачи.

0 голосов
/ 30 марта 2020

@ Огуз Озгул

 System.InvalidOperationException
      HResult=0x80131509
      İleti=Koleksiyon değiştirildi; sabit listesi işlemi yürütülemeyebilir.
      Kaynak=mscorlib
      StackTrace:
       konum System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
       konum System.Collections.Generic.List`1.Enumerator.MoveNextRare()
       konum System.Collections.Generic.List`1.Enumerator.MoveNext()
       konum System.Windows.Forms.DataVisualization.Charting.ChartTypes.FastLineChart.Paint(ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw)
       konum System.Windows.Forms.DataVisualization.Charting.ChartArea.Paint(ChartGraphics graph)
       konum System.Windows.Forms.DataVisualization.Charting.ChartPicture.Paint(Graphics graph, Boolean paintTopLevelElementOnly)
       konum System.Windows.Forms.DataVisualization.Charting.Chart.OnPaint(PaintEventArgs e)
       konum System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
       konum System.Windows.Forms.Control.WmPaint(Message& m)
       konum System.Windows.Forms.Control.WndProc(Message& m)
       konum System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       konum System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       konum System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

      Bu özel durum özgün olarak bu çağrı yığınında oluşturuldu: 
        [Dış Kod]
0 голосов
/ 30 марта 2020

Мне кажется, что у вас есть infinte loop здесь:

   while (true)
    {
        if (!kuyruk.IsEmpty)
        {
            if (kuyruk.TryDequeue(out pnt))
                chart1.Series[0].Points.AddY(pnt);
        }
    }

Вот почему вы получаете InvalidOperationException. Поставьте условие для выхода из while-loop.

Если проблема не исчезнет, ​​оставьте комментарий.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...