简体   繁体   English

C# 中图表的 System.ExecutionEngine 异常

[英]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.我正在尝试对传感器数据进行实时 plot。UI 由图表、启动和停止按钮组成。

When the start button is pressed, the data from sensor is plotted on the chart using a timer of 100ms.当按下开始按钮时,来自传感器的数据会使用 100 毫秒的计时器绘制在图表上。 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.如果我用 while(true) 循环替换更新值的计时器方式,则没有例外或其他问题。但在这种情况下,我将失去对 UI 其他部分的控制,因为我只使用 1 个线程。

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).在您的 UI 线程中使用while (true)时,您基本上会阻止所有其他与 UI 相关的功能(因为 UI 线程很忙)。

There are 3 common way's to overcome this problem:有3种常见的方法来克服这个问题:

  • use asyc/await: although I would not recommend it in your scenario.使用 asyc/await:虽然我不建议在您的场景中使用它。
  • add Application.DoEvents() to your loop, which is actually a hack to overcome the UI responsiveness.Application.DoEvents()添加到您的循环中,这实际上是一种克服 UI 响应能力的技巧。
  • 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.很可能您的 Timer 没有在 UI 线程上运行,这可能会在更新 UI 组件时导致问题。

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更多文档可以在MSDN上找到

Based on your description, you want to use a timer of 100ms and avoid locking the control when you use the above code.根据您的描述,您希望使用 100ms 的计时器并避免在使用上述代码时锁定控件。

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:结果:

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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