实时绘制几个图表,C#表格
我想从我的A / C的16个频道预览,我需要25-40Hz的刷新率(每25-40ms更新一次).我做了一些线程和定时器的组合,但我只获得了最多4个图表的令人满意的性能.在扩展图表范围以刷新后,添加图表的帧速率约为0.5 / s.我申请了快线图.
?我应用了一个计时器,每隔20ms从A / C获取新数据.经过一些测试后,看起来添加一个单独的线程来处理每个图表,这个图表会在给定时间内休眠,然后更新图表效率不高(至少按照我这样做的方式). ?所以问题是:如何有效地处理多个图表. 下面我介绍代码中最重要的部分. 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(); })); } } 更新: private void OnTimedEvent(object sender,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,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-40分钟重绘一次图表.当我只绘制一个绘图时,我可以达到此帧速率,因此不需要数据采集时间(A / C在背景中工作,Fs = 1k Hz).也许绑定队列到图表使它更快但不是很多. 我将更准确地描述我所进行的性能测试中发生了什么. 当nr = 10,np = 50时,图表1-6的行为与nr = 6的情况相同,而图表7-8令人惊讶地运行平稳,9-10表示像1fps. 当nr = 16,图1-8的行为类似于nr = 10的情况,而其他8的情况类似于0.05fps或其他. 无论我使用哪种方法,单线程,多线程,单/多调用,队列绑定,Thread.Sleep(),Threed.CurrentThread.Join(),Timers,async结果总是更不一样.老实说,我不知道为什么我无法在16个fastline图表上获得实时数据预览. 解决方法
老实说,我不认为多线程会对你有所帮助.在一天结束时,最重要的操作将是图表的更新,无论如何必须在UI线程上完成.
我建议您有一个单独的线程,每20ms获取所有最新值,然后在UI上调用单个Invoke,在单个Action中一次更新所有图表.每次更新多次调用会导致严重的性能损失. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |