在GUI线程使用集合之前,正在另一个线程中更改集合

本文关键字:线程 集合 另一个 GUI | 更新日期: 2023-09-27 18:27:01

我正在编写一个程序来记录称重传感器数据。数据收集是在一个单独的线程中完成的。数据存储在其中的集合,每0.5秒传递回UI,并在图形中显示。我正在使用foreach将其复制到ZedGraph的点列表中。问题是foreach循环有时在数据收集线程中用新数据更新集合之前不会完成。这会导致引发异常。

有人对我如何解决这个问题有什么建议吗?

ETA:

private void record()
        {
            stopwatch.Reset();
            stopwatch.Start();
            comport.Open();
            comport.DiscardInBuffer();
            comport.DiscardOutBuffer();

            //comport.Write(COMMAND_COLDRESET + Environment.NewLine);
            //comport.Write(COMMAND_CONTINUOUSMODE + "<CR>");
            comport.Write(COMMAND_CONTINUOUSMODE + Environment.NewLine);
            recordingStartTrigger(); //** Fire Recording Started Event
            TimeOut.Start();
            updateTimer.Start();
            this.waitHandleTest.WaitOne(); //** wait for test to end
            TimeOut.Stop();
            updateTimer.Stop();
            comport.sendCommand(COMMAND_COMMANDMODE + Environment.NewLine);
            comport.Close();
            recordingStopTrigger(status); //** Fire Recording Stopped Event
            stopwatch.Stop();
        }

        //***********************************************************************************
        //** Events Handlers

        private void comDataReceived_Handler(object sender, SerialDataReceivedEventArgs e)
        {
            double force = 0;
            TimeOut.Stop();

            string temp = comport.getBuffer(true);
            if (!this.stop)
            {
                //force = Convert.ToDouble(temp);

                if(double.TryParse(temp, out force))
                {
                    report.Readings.Add(new Models.Reading { Time = stopwatch.ElapsedMilliseconds, Force = force });
                }
            }
            else
            {
                this.WaitEventTest.Set(); //** triggers the record method to continue and end the test.
            }

            TimeOut.Start(); //** reset TimeOut Timer
        }

    void updateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        //** fire delagate that GUI will be listening to, to update graph.
        eventNewData(this, new eventArgsNewData(report));
    }

在GUI线程使用集合之前,正在另一个线程中更改集合

解决此问题的最简单方法是停止将集合发送到UI线程。这从根本上来说是不安全的,因为你在一个线程上阅读,而在另一个线程中写作。除非你使用的是专门为这项任务设计的集合,否则它将无法通过

以下是一些可能的解决方案

  1. 使用一个新的并发集合,如ConcurrentQueue<T>
  2. 将集合的副本传回UI线程

我的选择是#2。