我想预览我的空调的16个通道,并且我需要刷新率在25-40赫兹(每25-40毫秒更新一次)。我进行了几个线程和定时器的组合,但是我只能在最多4个图表上取得令人满意的性能。将图表范围扩展到刷新后,添加的图表帧速率约为0.5 / s。我应用了快速折线图。
我使用计时器每20ms从空调获取新数据。经过一些测试,看起来添加一个单独的线程以处理每个图表,该线程休眠一段时间,然后更新绘图并不高效(至少在我这样做的方式上)。
所以问题是:如何有效地处理多个图表。
下面是代码的最重要部分。
更新:
1.我已经将updatePlot()的功能移动到定时器的onTimedEvent中,现在它看起来像这样:
这些解决方案仅有微小的改进。不幸的是,在两种情况下,图表刷新速度仍然不够快。此外,charts []数组中的前8个刷新速度很快,而后8个的帧率约为0.5 Hz,这对我来说非常奇怪,因为它们没有以相同的方式运行。
更新2:
正如在第一篇文章中所述,我需要每20-40ms重新绘制图表。当我只绘制一个情节时,我可以实现这个帧速率,所以这不是数据收集时间的问题(A / C在后台以Fs = 1k Hz工作)。也许将队列绑定到图表上使它更快了,但并不是太多。
我将更详细地描述我进行的性能测试中发生的情况。
因此,当我将nr(要刷新的图表数)限制为6时,使用ti(时间间隔)20ms更新它们,因此它们在某一时刻存储50个点(np),它们都平稳运行。但是,当我将np更改为100时,仅图表1-4平稳运行,而图表5的速度变得非常慢,图表6几乎停止。 当nr = 6,ti = 20,np = 250时,图表1-3平稳运行,而图表4-6的运行方式如0.1fps。
当nr = 10,ti = 20,np = 50时,与nr = 6相同,图表1-6的行为方式相同,而令人惊讶的是,图表7-8平稳运行,图表9-10则像1fps。 当nr = 10,ti = 20,np = 100时,与nr = 6相同,图表1-6的行为方式相同(因此只有charts1-3平稳运行),而图表7-8仍然平稳运行,而图表9-10则像0.1fps。
当nr = 16,ti = 20,np = 50时,图表1-8的行为方式与nr = 10相同,另外8个则为0.05fps或类似。
无论我使用哪种方法,单线程、多线程、单/多调用、队列绑定、Thread.Sleep()、Threed.CurrentThread.Join()、Timers、异步,结果总是更少的相同。老实说,我不知道为什么我无法在16个快速线图上获得实时数据预览。
感谢任何建议。
我使用计时器每20ms从空调获取新数据。经过一些测试,看起来添加一个单独的线程以处理每个图表,该线程休眠一段时间,然后更新绘图并不高效(至少在我这样做的方式上)。
所以问题是:如何有效地处理多个图表。
下面是代码的最重要部分。
System.Timers.Timer tim = new System.Timers.Timer(20);
System.Threading.Thread[] t;
int HighChan = 15;
//button which runs the preview, executed once
private void previewB_Click(object sender, EventArgs e)
{
t = new System.Threading.Thread[HighChan + 1];
for (int i = 0; i <HighChan+1; i++)
{
charts[i].Series.SuspendUpdates();
//run a separate thread for each chart
t[i] = new System.Threading.Thread(new ParameterizedThreadStart(updatePlot));
t[i].Start(i);
}
//run timer to get new data with tim.interval
tim.Stop();
tim.Elapsed += new ElapsedEventHandler(this.OnTimedEvent);
tim.Start();
}
ushort[] ADData_prev;
//get new data from A/C every tim.interval
private void OnTimedEvent(object sender, EventArgs e)
{
ADData_prev = getPrev(); //gets new data, array wit 16 fields
// I also tried to suspend and resume threads t from this place but unsuccessfully
}
//update the chart with new data
void updatePlot(object chart_info)
{
int i = (int)chart_info;
while(true)
{
//wait for new data to read
Thread.CurrentThread.Join(20);
charts[i].Invoke(new Action(delegate()
{ charts[i].ResetAutoValues(); }));
// I skipped some conditions to make code clearer
//remove old point and add new one
charts[i].Invoke(new Action(delegate()
{
charts[i].Series[0].Points.RemoveAt(0);
charts[i].Series[0].Points.AddY(ADData_prev[i]);
}));
charts[i].Invoke(new Action(delegate()
{
charts[i].Series.ResumeUpdates();
charts[i].Series.Invalidate();
charts[i].Series.SuspendUpdates();
}));
}
}
更新:
1.我已经将updatePlot()的功能移动到定时器的onTimedEvent中,现在它看起来像这样:
private void OnTimedEvent(object sender, EventArgs e)
{
ADData_prev = getPrev(); //gets new data, array wit 16 fields
charts[0].Invoke(new Action(delegate()
{
for (int i = 0; i < HighChan + 1; i++)
{
//charts[i] stuff here
}
}
}
2. 我决定在onTimedEvent中更改bool变量,该变量允许在updatePlot()的while(true)循环中每次计时器的滴答绘制图表:
private void previewB_Click(object sender, EventArgs e)
{
for (int i = 0; i <= HighChan; charts[i++].Series.SuspendUpdates()) ;
t = new System.Threading.Thread(updatePlot);
t.Start();
//run timer to get new data with tim.interval
tim.Stop();
tim.Elapsed += new ElapsedEventHandler(this.OnTimedEvent);
tim.Start();
}
bool entry = false;
private void OnTimedEvent(object sender, EventArgs e)
{
ADData_prev = getPrev(); //gets new data, array wit 16 fields
entry = true;
}
void updatePlot()
{
while(true)
{
if(entry)
{
charts[0].Invoke(new Action(delegate()
{
for (int i = 0; i < HighChan + 1; i++)
{
//charts[i] stuff here
}
}
entry = false;
}
}
}
这些解决方案仅有微小的改进。不幸的是,在两种情况下,图表刷新速度仍然不够快。此外,charts []数组中的前8个刷新速度很快,而后8个的帧率约为0.5 Hz,这对我来说非常奇怪,因为它们没有以相同的方式运行。
更新2:
正如在第一篇文章中所述,我需要每20-40ms重新绘制图表。当我只绘制一个情节时,我可以实现这个帧速率,所以这不是数据收集时间的问题(A / C在后台以Fs = 1k Hz工作)。也许将队列绑定到图表上使它更快了,但并不是太多。
我将更详细地描述我进行的性能测试中发生的情况。
因此,当我将nr(要刷新的图表数)限制为6时,使用ti(时间间隔)20ms更新它们,因此它们在某一时刻存储50个点(np),它们都平稳运行。但是,当我将np更改为100时,仅图表1-4平稳运行,而图表5的速度变得非常慢,图表6几乎停止。 当nr = 6,ti = 20,np = 250时,图表1-3平稳运行,而图表4-6的运行方式如0.1fps。
当nr = 10,ti = 20,np = 50时,与nr = 6相同,图表1-6的行为方式相同,而令人惊讶的是,图表7-8平稳运行,图表9-10则像1fps。 当nr = 10,ti = 20,np = 100时,与nr = 6相同,图表1-6的行为方式相同(因此只有charts1-3平稳运行),而图表7-8仍然平稳运行,而图表9-10则像0.1fps。
当nr = 16,ti = 20,np = 50时,图表1-8的行为方式与nr = 10相同,另外8个则为0.05fps或类似。
无论我使用哪种方法,单线程、多线程、单/多调用、队列绑定、Thread.Sleep()、Threed.CurrentThread.Join()、Timers、异步,结果总是更少的相同。老实说,我不知道为什么我无法在16个快速线图上获得实时数据预览。
感谢任何建议。
updatePlot
方法在另一个线程中运行的目的是什么? - Sriram SakthivelSystem.Windows.Forms.Timer
。在Tick事件中更新数据。如果接收频率很高,则使用一个Queue
。 - Sriram Sakthivel