簡體   English   中英

C# 中圖表的 System.ExecutionEngine 異常

[英]System.ExecutionEngine Exception for charts in C#

我正在嘗試對傳感器數據進行實時 plot。UI 由圖表、啟動和停止按鈕組成。

當按下開始按鈕時,來自傳感器的數據會使用 100 毫秒的計時器繪制在圖表上。 但它會引發類似系統執行引擎異常的異常。 如果我用 while(true) 循環替換更新值的計時器方式,則沒有例外或其他問題。但在這種情況下,我將失去對 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 響應能力的技巧。
  • 使用計時器

您已經使用了最后一個選項,但遇到了錯誤。 很可能您的 Timer 沒有在 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 的計時器並避免在使用上述代碼時鎖定控件。

我建議你可以使用計時器來做到這一點。

這是您可以參考的代碼示例。

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

結果:

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM