简体   繁体   中英

System.ExecutionEngine Exception for charts in C#

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

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

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:

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM