0

I am trying to do the live plot of a sensor data.The UI consists of a chart, a start and stop button.

When the start button is pressed, the data from sensor is plotted on the chart using a timer of 100ms. But it throws an exception like System Execution Engine exception. There is no exception or other issues if I replace the timer way of updating values with a while(true) loop.But in that case I will lose my control over the other parts of UI, as I am using only 1 thread.

Suggestions / opinions / help welcome!

while (true) 
{ 
    chart1.Series[0].Points.Clear(); 
    // Get data from sensor using sensor sdk, 
    // The function returns 2 arrays, x-array and y-array of values to be plotted 
    // Display x and z values 
    chart1.Series[0].Points.DataBindXY(adValueX, adValueZ); 
    chart1.Update(); 
    System.Threading.Thread.Sleep(100); 
}
Stefan
  • 17,448
  • 11
  • 60
  • 79
Arjun
  • 13
  • 4
  • 1
    Hi, please show your code and the full exception. – Stefan Jul 20 '20 at 06:15
  • while (true) { chart1.Series[0].Points.Clear(); // Get data from sensor using sensor sdk, // The function returns 2 arrays, x-array and y-array of values to be plotted // Display x and z values chart1.Series[0].Points.DataBindXY(adValueX, adValueZ); chart1.Update(); System.Threading.Thread.Sleep(100); } – Arjun Jul 20 '20 at 07:27
  • Hi, thanks for the code, now please [edit] your question to include the full exception and at which line it is raised. It would also help if you mention in which method this piece of code is running: is it a thread? an event handler? etc – Stefan Jul 20 '20 at 07:33
  • The above code works, but as the while loop starts, I lose my control over the form.No other buttons or even moving the form is disabled.Just the graph gets updated. So I used a timer to do the same with , when ever timer is ticked(at 100ms), the values will be updated in the chart.In that case, my issue is System.ExecutionEngineException and no other informaton regarding it, on which line or any details like that – Arjun Jul 20 '20 at 07:39
  • @Arjun,Is any update? If your question has been solved , you can click '✔' to mark the appropriate reply as the answer. – Jack J Jun Aug 04 '20 at 02:04

2 Answers2

0

When using while (true) in your UI thread, you're basically blocking all other UI related functionality (because the UI thread is busy).

There are 3 common way's to overcome this problem:

  • use asyc/await : although I would not recommend it in your scenario.
  • add Application.DoEvents() to your loop, which is actually a hack to overcome the UI responsiveness.
  • use a Timer

You already used this last option, and hit an error. Most likely your Timer was not running on the UI thread, which can cause problems while updating UI components.

There are various ways to fix it: here's one:

protected void OnYourTimerEventHandler()
{
    BeginInvoke(new MethodInvoker(delegate 
    {
        chart1.Series[0].Points.Clear(); 
        // Get data from sensor using sensor sdk, 
        // The function returns 2 arrays, x-array and y-array of values to be plotted 
        // Display x and z values 
        chart1.Series[0].Points.DataBindXY(adValueX, adValueZ); 
        chart1.Update(); 
    }));
}

More documentation can be found on MSDN

Stefan
  • 17,448
  • 11
  • 60
  • 79
0

Based on your description, you want to use a timer of 100ms and avoid locking the control when you use the above code.

I suggest that you can use timer to do it.

Here is code example you can refer to.

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        Dictionary<double, double> dic = new Dictionary<double, double>();
        private void Form1_Load(object sender, EventArgs e)
        {
            chart1.Series.Clear();
            var series1 = new System.Windows.Forms.DataVisualization.Charting.Series
            {
                Name = "Series1",
                Color = System.Drawing.Color.Green,
                IsVisibleInLegend = false,
                IsXValueIndexed = true,
                ChartType = SeriesChartType.Line
            };

            this.chart1.Series.Add(series1);
            series1.Points.AddXY(1, 10);
            series1.Points.AddXY(2, 14);
            chart1.Invalidate();
            timer1.Interval = 100;
            dic.Add(1, 20);
            dic.Add(2, 30);
            dic.Add(3, 40);
            dic.Add(4, 60);
            dic.Add(5, 70);

        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            chart1.Series[0].Points.Clear();
            // Get data from sensor using sensor sdk, 
            // The function returns 2 arrays, x-array and y-array of values to be plotted 
            // Display x and z values 
            chart1.Series[0].Points.DataBindXY(dic.Keys, dic.Values);
            chart1.Update();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            timer1.Start();
        }
    }

Result:

enter image description here

Jack J Jun
  • 5,633
  • 1
  • 9
  • 27