频繁绘图导致界面卡顿

weixin_38058939 2017-09-01 07:14:54

WPF做界面,通过调用硬件提供的DLL来控制数据采集,每次采集8192个点。需要进行循环采样,用来调试一些参数是否合适(采样点数固定为8192)。我用了一个bool IsRunning来判断机器是否正在采样。

整个逻辑是: ToggleButton Check->

提交参数->采样->(采样结束后)显示数据->提交参数->采样->显示数据->...

除非ToggleButton UnCheck,否则一直循环。在整个过程中,用户可以任意更改某个参数。

一开始的时候,我在ToggleButton的Check事件回调函数里面直接用while循环来确保采样结束后才取数据并显示
while (Iface.IsRunning()) { };//然后再GetData (硬件DLL提供)

这样做了之后发现界面会假死,百度说是要用后台线程来取数据和更新绘图,但是取数据要用到DLL中的GetData,而GetData一放到后台线程中就报“外部组件发生错误”(不知道为何~)

于是,我又换成了
TimerGS = new DispatcherTimer(DispatcherPriority.Render); TimerGS.Tick += new EventHandler(TimerGS_Tick); TimerGS.Interval = new System.TimeSpan(0, 0, 0, 0, 10); private void TimerGS_Tick(object sender, EventArgs e) { if (vm.Interrupt) { topScan(); IsRunning = false; TimerGS.Stop(); return; } if (IsRunning()) { IsRunning = true; return; } IsRunning = false; //IsRunning 是属性也是函数,不知道为何会这样,但是确实不报错~ commitParameter(); StartScan(); while (IsRunning()) { }; data = new TComplex[len]; GetData(data, len); UpdateData(); SamplingPlot.InvalidatePlot(true); System.Diagnostics.Debug.WriteLine("Tick Tick Tick..."); }

这样做下来功能是实现了,界面也没有假死,但是,界面变得非常卡顿,TextBox里面填入一个数字都要半天。

不知道这个问题如何解决?
...全文
31 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_38146511 2017-09-15
  • 打赏
  • 举报
回复
哈哈哈,换成位图之后动画非常流畅,非常感谢您的指导!!!
正在研究如何传递事件~~~
weixin_38144369 2017-09-14
  • 打赏
  • 举报
回复
绘图速度是很慢,但是如果把chart换成image,那显示完之后界面应该不会卡了吧。
weixin_38138643 2017-09-14
  • 打赏
  • 举报
回复
这个看上去很高端~~~但是我不大明白~~~~
位图缓存怎么得到呢?比如我用OxyPlot,不显示出来也能画图?是把Visibility设置为false 还是 Export(plotModel,
stream)?
(另外,调用export这个函数的时候难道不用显示出来么?官方的例子都是先画出来,然后再保存。那先画出来了岂不是还是卡?)
能不能给我一个简单的例子,就用oxyplot画图好了~~~多谢!
weixin_38126784 2017-09-14
  • 打赏
  • 举报
回复
比如:VisualTarget.RootVisual = Plot(一个OxyPlot.Wpf.Plot实例)
 UI线程中
void Render(数据 data) { Plot.Dispatcher.Invoke(绘data)}是这样的逻辑么?
weixin_38126752 2017-09-14
  • 打赏
  • 举报
回复
数据都是在UI线程得到,请问如何向HostVisual传递数据呢?
weixin_38125855 2017-09-13
  • 打赏
  • 举报
回复
如果绘图区域需要交互呢?比如缩放、pan……
weixin_38125291 2017-09-13
  • 打赏
  • 举报
回复
???
weixin_38068013 2017-09-13
  • 打赏
  • 举报
回复
???
weixin_38122767 2017-09-12
  • 打赏
  • 举报
回复
谢谢您的答复!我把所有操作都放到一个线程里面,是比之前的版本好多了,谢谢!
但是目前还是有明显的卡顿,特别是动画,能够看到明显的跳帧。

另外,有没有办法实现从UI线程或者别的线程向HostVisual传递数据?相关的资料非常少,基本上就只有msdn里的那一篇博文。

weixin_38067813 2017-09-09
  • 打赏
  • 举报
回复
???
weixin_38121708 2017-09-09
  • 打赏
  • 举报
回复
???
???1111 2017-09-08
  • 打赏
  • 举报
回复
无法更改底层dll
weixin_38118043 2017-09-08
  • 打赏
  • 举报
回复
建议跨线程调用才能降低你的效能,尽可能减少使用静态方式呼叫。
weixin_38107349 2017-09-06
  • 打赏
  • 举报
回复
UI线程的版本:
1. Window_Loaded: Helper.CreateBridge();
2. Button_Clicked: Helper.StartScan(TScanMode.Default);  然后GetData()
一切正常。

后台线程调用版本1:
提示外部组件发生异常。
后台线程调用版本2:
一切正常,但是
Helper.CreateBridge();
每次都要弹出启动界面,且持续时间太长。
不知道应该如何处理。
weixin_38110396 2017-09-06
  • 打赏
  • 举报
回复
Hi,
从你的描述上来看,组件报异常应该是没有调用 Helper.CreateBridge(); 这句话导致的。
从这代码的字面意思,应该是做一些初始化的操作,你这个组件的第三方的吗? 我觉得你应该和这个组件的创建者讨论一下。
这样会更快速的解决问题。
>>" 每次都要弹出启动界面,且持续时间太长。  "
你有办法把这个界面先隐藏起来吗?在数据拿到之前,不然他显示,或者用另外一个界面覆盖当前界面。
weixin_38092497 2017-09-05
  • 打赏
  • 举报
回复
Hi,

感谢你详细的反馈信息。 

>>"  DLL的CS接口文件中只有一个静态类Helper,静态类中只有这四个静态成员函数,为什么不能跨线程调用? "

我不太清楚你现在遇到的问题是不是由于这个静态成员导致的,但是静态成员在跨线程调用的使用,是特别需要主要资源保护的。

不然就会出现共享资源访问冲突导致程序出一些想不到的错误。

你可以尝试用锁来保护这些静态变量。 

lock Statement 

weixin_38088241 2017-09-04
  • 打赏
  • 举报
回复
外部dll中有四个函数
CreateBridge() 在程序打开的时候在UI线程调用。
DestroyBridge()在程序退出时UI线程调用。
(1)如果StartScan和GetData在UI线程中调用,可以得到正确的结果,但是界面会无响应;如果在后台线程中调用,直接报错:外部组件发生异常。
(2)如果在后台线程中先调用CreateBridge再调用StartScan和GetData,也能得到正确的结果。但是,每次调用CreateBridge都会弹出一个启动画面,持续数秒,所以不能频繁调用CreateBridge。
请问为什么会这样? DLL的CS接口文件中只有一个静态类Helper,静态类中只有这四个静态成员函数,为什么不能跨线程调用?





weixin_38082021 2017-09-04
  • 打赏
  • 举报
回复
谢谢您的回复。
我的取数据是调用的一个dll,这个dll运行时是带界面的,左侧参数面板右侧数据显示。在这个dll运行的界面上修改参数和数据显示非常流畅,估计已经使用了多线程。

现在需要从dll返回数据,到我自己的软件上面显示。现在的问题是,我用await Task async来调用dll中的任何一个函数,都会提示外部组件发生错误,所以我改成了用计时器。不知道是不是dll有什么限制,还是说我用的多线程方式不正确?
weixin_38068894 2017-09-01
  • 打赏
  • 举报
回复
Hi,
感谢你在

430

社区成员

发帖
与我相关
我的任务
社区描述
其他技术讨论专区
其他 技术论坛(原bbs)
社区管理员
  • 其他技术讨论专区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧