求大神指点,mfc使用线程优化程序

陈小俊的人生bug 2020-12-22 12:12:25
我的mfc界面有很多控件需要刷新,而且很频繁,造成程序卡顿,想使用线程优化界面。 如图1,是我的界面的一部分,图2是串口接收数据,图3是串口数据的解析。界面刷新是通过一个类似图3的一个函数实现的 void CTestselfDlg::DlgAutoCheck(BYTE * ReceiveData, bool reset) 我想使用线程专门处理数据和界面,但是尝试了很多网上的办法也没有实现。求指点!!!
...全文
676 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
sevancheng 2021-02-22
  • 打赏
  • 举报
回复
有变化再刷新,减少不必要的控件刷新
牧童吃五谷 2021-02-17
  • 打赏
  • 举报
回复
建议做这种工业数据监控的项目,可以考虑采用监控组态软件,几百块钱就可以搞定监控组态软件,然后花半天就可以画完画面,而且基本不需要调试,这种软件把高速工业数据通讯、历史数据存储、漂亮的屏幕动画展示、趋势图、数据统计等等都做好了,而且还都是有自己专门为工业监控开发的脚本编译系统。 当然公司有需要一定要自己编写程序那就只能这样了。
hhhh63 2020-12-29
  • 打赏
  • 举报
回复
我做的工作与你的类似,一台电脑与十几台AGV通讯,方法是,每台AGV一个通讯线程,还有其它的控制点也是线程,主进程显示数据。每个线程用死循环方式与站点通讯,周期约50ms,保证实时性。不是每次数据改变都显示,太快了,人眼也看不过来。定时100ms显示一次数据,效果不错,显示太快了也没用。
蒋晟 2020-12-27
  • 打赏
  • 举报
回复
这么多复选框可以用列表替代,不用那么多窗口。 然后更新频率没有太高要求的话,可以用定时器,比如用一个数组保存状态,用定时器每500毫秒刷新一次。你的串口通讯线程只负责去写入这个数组的值。
gz_qmc 2020-12-27
  • 打赏
  • 举报
回复
这么几个数据好简单,告诉你一个完美的封装方案

1个设备的类比如CDevice,定义好需要的数据块,
比如,char IB[1024];
比如,char OB[1024];

4个线程序
4个事件
4个函数
完美解决一切疑难杂症
线程序1管从通讯口读数据
线程序2管往通讯口写数据
线程序3管通讯连接(好处多多,断线检查及自动连接,呵呵呵)
线程序4管调度调度1和2
读数据的开始和结束各用1个事件
收到指令干活(事件1),干完报告(事件2)
写数据的开始和结束各用1个事件
收到指令干活(事件3),干完报告(事件4)

函数1: 发事件1,等事件2.实现光收不发
函数2: 发事件3,等事件4.实现光发不收,呵呵呵
函数3: 发事件1,等事件2.然后发事件3,等事件4. 实现先收后发(服务器类型)
函数4: 发事件3,等事件4.然后发事件1,等事件2. 实现先发后收(客户端类型)(PLC就用这种)

不用考虑同步异步的概念,就直接API完成
数据解析到自己类里.和界面框架没有1毛钱关系
从此以后不再操心关于通讯的卵事情.通通的死了死了的.

定义全局的东东
CDevice PlcS71200;
PlcS71200.Run();
呵呵呵

关于窗口界面,别用控件
for(int=0;i<10000;I++)
{
画就完了
}
  • 打赏
  • 举报
回复
引用 4 楼 陈仲甫的回复:
你可以先找出瓶颈在哪里(未必是在界面刷新,100多个复选框,我认为操作起来并不会出现非常明显的延迟), 你可以写一个测试代码,不从ReceiveData拿数据,设置一轮所有的控件,看用时多久; 然后再测试一下你的实际代码,中间相差时间很多的话,肯定就是ReceiveData太慢了; 如果确实是ReceiveData的问题,那么你可以: A、单独一个线程建立显示窗口,并设置控件状态;另一个线程只管ReceiveData,并把收到的数据PostMessage给UI线程,这样不会打断刷新UI的过程; B、减少接收数据的时间开销,由于我很少用这个MSComm所以不确定是否支持以下操作: 1、以非阻塞模式读取串口,还可以将串口完成事件关联到IOCP(更复杂的编程模型,你发出异步的请求后,程序可继续往下走,操作系统会通知你操作完成); 2、可以考虑状态在发送方组合成一个整体的数据块。一次收发一批传感器的状态。 串口操作库推荐http://www.naughter.com/serialport.html
这个复选框不止100多,将近300个。之前我是一次全部刷新,现在我把他们对应分成7部分依次刷新了了,但是运行久了还是有卡死现象
  • 打赏
  • 举报
回复
引用 3 楼 mmcanyu的回复:
CSerialPort,CnComm。 我个人用的一直是CnComm。
这些类我都没有使用过,可以尝试看看,谢谢!
Eleven 2020-12-23
  • 打赏
  • 举报
回复
图1你完全可以用TabControl + 子CDialog去做,你两个界面内容基本一致。
schlafenhamster 2020-12-23
  • 打赏
  • 举报
回复
CWnd::LockWindowUpdate BOOL LockWindowUpdate( ); Return Value Nonzero if the function is successful. It is 0 if a failure occurs or if the LockWindowUpdate function has been used to lock another window. Remarks Disables drawing in the given window. A locked window cannot be moved. Only one window can be locked at a time. To unlock a window locked with LockWindowUpdate, call UnlockWindowUpdate.
mmcanyu 2020-12-23
  • 打赏
  • 举报
回复
如果是控件太多刷新慢,那么这些控件得自己绘制,效率会快很多。 不过首先还是要处理主窗口接收数据处理数据的问题。
an_bachelor 2020-12-22
  • 打赏
  • 举报
回复
你可以先找出瓶颈在哪里(未必是在界面刷新,100多个复选框,我认为操作起来并不会出现非常明显的延迟), 你可以写一个测试代码,不从ReceiveData拿数据,设置一轮所有的控件,看用时多久; 然后再测试一下你的实际代码,中间相差时间很多的话,肯定就是ReceiveData太慢了; 如果确实是ReceiveData的问题,那么你可以: A、单独一个线程建立显示窗口,并设置控件状态;另一个线程只管ReceiveData,并把收到的数据PostMessage给UI线程,这样不会打断刷新UI的过程; B、减少接收数据的时间开销,由于我很少用这个MSComm所以不确定是否支持以下操作: 1、以非阻塞模式读取串口,还可以将串口完成事件关联到IOCP(更复杂的编程模型,你发出异步的请求后,程序可继续往下走,操作系统会通知你操作完成); 2、可以考虑状态在发送方组合成一个整体的数据块。一次收发一批传感器的状态。 串口操作库推荐http://www.naughter.com/serialport.html
mmcanyu 2020-12-22
  • 打赏
  • 举报
回复
CSerialPort,CnComm。 我个人用的一直是CnComm。
  • 打赏
  • 举报
回复
引用 1 楼 mmcanyu的回复:
首先你应该在线程中接收处理串口数据,不要用mscomm这个控件,改用其他串口类。 线程中处理完需要刷新显示时,发送消息让窗口刷新。 主窗口频繁刷新这些控件应该没压力了。
那我应该用哪个类比较好?
mmcanyu 2020-12-22
  • 打赏
  • 举报
回复
首先你应该在线程中接收处理串口数据,不要用mscomm这个控件,改用其他串口类。 线程中处理完需要刷新显示时,发送消息让窗口刷新。 主窗口频繁刷新这些控件应该没压力了。

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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