System.ExecutionEngine C# 图表异常

System.ExecutionEngine Exception for charts in C#

我正在尝试绘制传感器的实时绘图 data.The UI 由图表、开始和停止按钮组成。

按下开始按钮时,使用 100 毫秒的计时器将来自传感器的数据绘制在图表上。 但它会抛出一个异常,如系统执行引擎异常。如果我用 while(true) loop.But 替换计时器更新值的方式,则没有异常或其他问题,在这种情况下,我将失去对 UI 其他部分的控制,因为我正在使用只有 1 个线程。

欢迎提出建议/意见/帮助!

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

在您的 UI 线程中使用 while (true) 时,您基本上会阻止所有其他 UI 相关功能(因为 UI 线程正忙)。

有 3 种常用方法可以解决此问题:

  • 使用 asyc/await :虽然我不会在您的情况下推荐它。
  • Application.DoEvents() 添加到您的循环中,这实际上是克服 UI 响应能力的技巧。
  • 使用定时器

您已经使用了最后一个选项,但遇到了错误。很可能您的计时器不在 UI 线程上 运行,这可能会在更新 UI 组件时导致问题。

有多种方法可以修复它:这是一个:

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

可以在 MSDN

上找到更多文档

根据您的描述,您希望使用100ms的定时器,避免在使用上述代码时锁定控件。

我建议你可以用timer来做。

这是您可以参考的代码示例。

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

结果: