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();
}
}
结果:
我正在尝试绘制传感器的实时绘图 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();
}
}
结果: