Delphi indy线程控件TIdThreadComponent的使用
当程序需要做耗时操作,例如访问数据库获取较多的数据、获取大文件MD5、网络访问数据量比较大、界面需要频繁刷新等等,都可以用线程来解决界面卡顿的问题,从而优化用户体验。
在知道TIdThreadComponent之前,建立线程一般都使用继承TThread复写execute过程或者使用createthread。继承TThread写的代码要多一点,createthread又不方便控制线程,于是就有了TIdThreadComponent,集两者的优点,只要拖个控件,线程就出来了。
TIdThreadComponent用的是观察者模式(就是回调),提供以下几个事件回调:
OnAfterExecute; //线程Execute过程执行完成
OnAfterRun; //线程循环执行体完成(不明白的下面看了原理就能明白)
OnBeforeExecute;//线程Execute过程执行之前
OnBeforeRun;//线程循环执行体之前(不明白的下面看了原理就能明白)
OnCleanup;
OnException;
OnRun;//执行体
OnStopped;
OnTerminate;
原理如下,下图是为了方便理解使用,忽略了一些不常用的细节,例如OnStopped;OnCleanup;事件的回调时机,有兴趣的可以查看控件源码,熟悉线程的同学应该都能看懂并理解源码。
onRun会被重复执行,直到调用控件的stop过程或Terminate过程;
before前缀的回调事件多用于初始化工作,一般建议使用beforeExecute;
after前缀的回调事件多用于释放内存操作,一般建议使用afterExecute;
控件提供stop函数和Terminate函数,进行对线程的停止操作,届时会触发并回调onstop、onTerminate事件,需要结束线程时,建议使用stop函数或active:=false;
控件的使用
前提需要安装indy系列,我用的是indy9(我尝试过在Delphi2010上使用indy10,beforeRun和afterRun的触发时机有点不一样)
1.把TIdThreadComponent控件拖到窗体上
2.根据业务需求,在相应的回调事件中写业务处理代码
3.TIdThreadComponent.active := true 开始执行
4.执行效果
在onRun中模拟耗时操作,在onRun执行耗时操作时,界面没有被卡死,依然可以流畅拖动,做其它事情
onRun事件处理代码
beforeExecute、afterExecute执行的代码:
start按钮和stop按钮执行的代码
这样,一个线程操作就完成了,非常的方便。
TIdThreadComponent还提供了设置线程优先级,这些就不做介绍了。
注意:
在线程里直接操作界面控件是一件危险的事情,有时候控件被销毁了而线程还在运行,此时就会报AV异常,所以在TIdThreadComponent回调事件中有使用到控件的,必须添加控件是否为空判断,例如我代码里写到的
否则,在TIdThreadComponent线程运行期间,关闭窗体会造成异常。
当然你可以使用消息来处理,但消息参数handle要用变量保存,否则也会报错。
注意2:
如果TIdThreadComponent没有开启(即没有active:=true或start),直接TIdThreadComponent.Terminate会出异常,而TIdThreadComponent.stop不会
Delphi indy线程控件TIdThreadComponent的使用的更多相关文章
- Handler机制来处理子线程去更新UI线程控件
public class HandlerTestActivity extends Activity { private TextView tv; private static final int UP ...
- C# 跨线程访问或者设置UI线程控件的方法
一.背景 在C#中,由于使用线程和调用UI的线程属于两个不同的线程,如果在线程中直接设置UI元素的属性,此时就会出现跨线程错误. 二.问题解决方法 使用控件自带的Invoke或者BeginInvoke ...
- Delphi - Indy TIdFTP控件实现文件的上传和下载
FTP信息保存和获取 我们在做FTP相关开发时,为方便后续FTP切换,一般先把FTP账户信息保存到数据库表中,在使用时再通过Query获取出来. 一般通过如下方式获取到FTP相关信息,代码如下: // ...
- [delphi]indy idhttp post方法
网易 博客 LOFTCam-用心创造滤镜 LOFTER-最美图片社交APP 送20张免费照片冲印 > 注册登录 加关注 techiepc的博客 万事如意 首页 日志 LOFTER 相册 音乐 ...
- 在Winform开发中使用日程控件XtraScheduler(2)--深入理解数据的存储
在上篇随笔<在Winform开发中使用日程控件XtraScheduler>中介绍了DevExpress的XtraScheduler日程控件的各种使用知识点,对于我们来说,日程控件不陌生,如 ...
- 在Winform开发中使用日程控件XtraScheduler
在一些应用场景中,我们可能需要记录某一天,某个时段的日程安排,那么这个时候就需要引入了DevExpress的日程控件XtraScheduler了,这个控件功能非常强大,提供了很好的界面展现方式,以及很 ...
- Delphi连接Oracle控件ODAC的安装及使用(轉載)
Delphi连接Oracle控件ODAC的安装及使用 2010-08-13 01:13:37 标签:Oracle Delphi 控件 休闲 ODAC 原创作品,允许转载,转载时请务必以超链接形式标明 ...
- zw版【转发·台湾nvp系列Delphi例程】Delphi 使用 HALCON库件COM控件数据格式转换
zw版[转发·台湾nvp系列Delphi例程]Delphi 使用 HALCON库件COM控件数据格式转换 Delphi 使用 HALCON库件COM控件数据格式转换,与IHObjectX接口有关 va ...
- Delphi的TListView控件拖放选定行操作
http://www.tansoo.cn/?p=401 Delphi的TListView控件拖放选定行操作的例子,效果图如下:TListView控件拖动选定行到指定位置 具体实现步骤: 一.新建一个D ...
随机推荐
- java0425 wen IO
- SOAR SQL进行优化和改写的自动化工具
前言 SQL优化是程序开发中经常遇到的问题,尤其是在程序规模不断扩大的时候.SQL的好坏不仅制约着程序的规模,影响着用户的体验,甚至威胁着信息的安全. 我们经常听到说哪家平台挂了,哪家网站被黑了,但我 ...
- 集束搜索beam search和贪心搜索greedy search
贪心搜索(greedy search) 贪心搜索最为简单,直接选择每个输出的最大概率,直到出现终结符或最大句子长度. 集束搜索(beam search) 集束搜索可以认为是维特比算法的贪心形式,在维特 ...
- 大数据开发认知--spark
1. Spark rdd生成过程· Spark的任务调度分为四步 1RDD objects RDD的准备阶段,组织RDD及RDD的依赖关系生成大概的RDD的DAG图,DAG图是有向环图. 2DAG s ...
- C#Razor模板引擎简单使用
引用 install-package RazorEngine 使用 public class TestDemo { private string name; public int Age { get ...
- Java集合与泛型中的陷阱
List,List<Object>区别 List<Integer> t1 = new ArrayList<>(); // 编译通过 List t2 = t1; // ...
- speech
1.李开复:一个人的成功,15%靠专业知识,其余15%人际沟通,公众演讲,以及影响他人的能力 2.演讲是一门遗憾的艺术 3.没有准备就等于准备失败 4.追求完美,就是在追求完蛋 5.宁可千日无机会,不 ...
- firefox(火狐)下 js中设置checkbox属性checked="checked"已有,但复选框却不显示勾选的原因
刚看到问题时以为是浏览器兼容性的原因,ie.google都能正常显示. 网上查询之后发现是jQuery的attr()方法用的不恰当. jQuery1.6之前使用attr()可以修改 ,从jQuery ...
- webpack创建页面的过程
1.项目文件夹中创建各类型文件放置的文件夹,如:iTestingWeb文件夹下创建src dist文件夹,用途:src为源码 dist为生成后的文件放置位置,然后在源码文件夹中进一步按文件类型增加文件 ...
- javascript 删除 url 中指定参数,并返回 url
// 删除url中某个参数,并跳转function funcUrlDel(name){ var loca = window.location; var baseUrl = loca.origin + ...