1

I'm writing a program to record load cell data. The data collecting is done in a separate thread. The collection the data is stored in, is passed back every .5 seconds to the UI where is it displayed in a graph. I'm using a foreach to copy it into a points list for ZedGraph. The problem is that the foreach loop doesn't finish sometimes, before the collection gets updated with new data in the data collection thread. This causes an exception to get thrown.

Does anyone have any suggestions on how I can fix this problem?

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));

    }
4

1 回答 1

2

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

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

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

我的选择是#2。

于 2013-08-08T21:49:10.633 回答