zoukankan      html  css  js  c++  java
  • 后台线程更新界面的巧妙方法

    在单机版程序的设计中,对于需要较长时间运行的操作,一般都通过后台线程来完成。如果直接用 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

    转载请注明出处: http://www.cnblogs.com/jacklondon ; 欢迎访问 http://www.zheguisoft.com/ 并提建议。
  • 相关阅读:
    delphi res 字符串资源
    delphi label1 文字在窗体上水平来回移动
    delphi Edit
    delphi CoolBar这个怎么弄没了
    delphi Components[i]清除所有edit控件中的内容
    delphi Caption 垂直显示标签文本
    delphi array应用 DayOfWeek星期几判断
    delphi 2010 资源文件使用
    delphi 18 屏蔽和替换 右键菜单
    delphi 16 网页缩放
  • 原文地址:https://www.cnblogs.com/jacklondon/p/2451403.html
Copyright © 2011-2022 走看看