后台线程更新界面的巧妙方法
来源:互联网 发布:圆弧插补指令编程实例 编辑:程序博客网 时间:2024/06/04 18:25
在单机版程序的设计中,对于需要较长时间运行的操作,一般都通过后台线程来完成。如果直接用 UI 线程(在 click 事件中) 运行,则 UI 界面长时间得不到机会重新绘制,会造成程序假死的现象(俗称“翻白眼”)。
后台线程更新界面有一些注意事项:
1. 后台线程一般不能直接操作界面控件,需要调用 invoke 之类的函数;
2. 后台线程更新界面的频次不能太慢,太慢则也容易让用户觉得程序“死掉了”;
3. 后台线程更新界面不能太快,一来界面更新太快人眼看不清,容易让人觉得程序好像失控了,在胡乱显示一些乱码;二来,界面更新太快,也会影响整个操作的完成速度,更新界面也是需要 CPU 的。我们知道,电影每秒是 24帧,也就是说,每秒更新画面 24 次,是可以让人觉得很流畅的,每秒更新超过 24 次是不必要的。
如果只有问题1 ,则还比较好处理。网上很多讲述 invoke 之类的函数。虽然麻烦,也还算在可控范围。
对于问题2/3, 则不容易处理。比如,我的程序是批量复制文件,在我的开发计算机上经过测试,每复制 10 个文件,更新一下界面,看起来比较好。程序就这么写了。
交付给用户之后,如果用户的计算机比我的计算机快了很多,或者慢了很多,则运行界面效果还是不理想:不是更新太快、就是更新太慢。
解决办法是:
更新用户界面,采用定时器 timer ,取名 UpdateUiTimer。后台线程运行过程中,把运行状态(百分比、状态提示详细字符串、主要步骤字符串)放入全局变量中,UpdateUiTimer 来读取全局变量并显示。定时器运行间隔,可以设置成每秒 2 –5 次(我的经验值)。invoke 之类的函数就不要调用了。这样可以解决问题。
全局变量类设计,可以为这样的形式:
public class GlobalVars
{
public static int RunningPercent;
public static string RunningMainStepStatus;
public static string RunningDetailStepStatus;
}
这里有几个注意事项:
a. 多线程对同一个变量的读写,如果不加特别控制,是有一点缓存、延迟的。也就是说,一个线程对变量的更改,并不一定会被另一个线程读到。举例来说,工作线程先更新完成进度为 5%, 然后更新为 10%,这时候 timer 去读取进度,有可能读到 5%,下次才能读到 10%。不过这点对我们的显示程序逻辑,不构成多大影响。
b. 后台线程运行的时候,最好把界面 disable,不然用户可能点击两次按钮,或者在后台在运行的时候,做别的事情,有可能会互相影响。
-------------转载请注明来源:http://www.cnblogs.com/jacklondon
-------------欢迎大家下载试用折桂单点登录系统, http://zheguisoft.com
- 后台线程更新界面的巧妙方法
- wxpython后台线程更新界面控件方法
- 后台线程使用 SynchronizationContext 更新主界面
- c#中后台线程更新主线程ui的方法
- 在分线程更新主线程的Ui界面方法
- 线程更新UI界面的4种方法
- 非UI线程更新UI界面的各种方法小结
- 非UI线程更新UI界面的各种方法小结
- ios后台更新界面
- VS2005中更新其他线程访问界面线程控件的方法
- androidUI界面的更新方法
- Android学习札记30:线程更新UI界面的4种方法
- 子线程更新界面
- android AsyncTask 可以更新界面的后台任务
- 界面与后台工作线程分离的实现方案
- 界面与后台工作线程分离的方案
- iphone开发,ui界面和后台线程的运行机制
- android异步更新UI界面的方法
- 时间复杂度的计算
- IOException while loading persisted sessions: java.io.EOFException
- 关于查询函数的建立
- JAVA内存占用
- [HDU 1394]求全排列逆序数最大值[线段树]
- 后台线程更新界面的巧妙方法
- Java国际化梳理
- 水仙花数
- 学C/C++课程还花钱?你OUT了!
- ubantu12.4 下搭建android编译环境
- [poj 1166]敌兵布阵[线段树基础]
- java跨平台性分析
- hdu 3579(中国剩余定理)
- c/c++ 数字转成字符串, 字符串转成数字