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 ...
随机推荐
- axios请求
axios.get('/user?ID=12345') .then(function (response) { console.log(response); console.log(response. ...
- 使用aspx 直接生成excel
<%@ Page Language="C#" EnableEventValidation="false" ResponseEncoding="g ...
- java eclipse war包的二次开发方法
有实际项目在跑的war包,却没有源码,苦于想查看源码,身处运维组为研发组看不起,拿不到源码,只能自己来反编译了. 只要你细心点,其实在解压war包后,可以看到文件夹中,已经存在了jsp文件,但是却没有 ...
- 【Mongo】安装并配置副本集
最近的一个小项目需要用到mongo,所以开始学习下mongo.本打算开三台虚机严格按照生产来配置,然后发现有点带不动,所以决定在一台上通过三个端口来模拟. 1.获取安装包 curl -O http:/ ...
- 七夕节快到了,做个图钉画以及学习下Pillow吧
又有时间写东西了,最近深感世事并不以人的美好愿望而改变,还是要以积极地心态来适应新变化,多多关心身边的人. 图钉画中一个图钉代表一个像素,所以关键在于像素渣化,降低分辨率,图钉的色彩有限,还需要降低图 ...
- java.lang.IllegalStateException: getWriter() has already been called for this response
出现此异常的三种可能: 1.通过response.reset(); 刷新可能存在一些未关闭的getWriter(). 来源:http://blog.csdn.net/wonder4/article/ ...
- autoit脚本-从基本的函数用法开始
适配浏览器:目前了解的有ie浏览器 MsgBox 显示可选提示超时的消息框 _ArrayDisplay _arraydisplay($aArray) ;$aArra一般为数组,方法用于展示表格展示数 ...
- Jenkins学习
1.jenkins启动卡在密码初始化处不动的情况,参照: https://blog.csdn.net/lylload/article/details/82754101 https://blog.csd ...
- 20175312 2018-2019-2 实验一《Java开发环境的熟悉》实验报告
20175312 2018-2019-2 实验一<Java开发环境的熟悉>实验报告 实验内容 1.使用JDK编译.运行简单的Java程序: 2.使用Eclipse 编辑.编译.运行.调试J ...
- Chrom Firefox 非安全端口访问
使用Chrom Firefox 访问非安全端口 问题描述 Firefox 此网址已被限制 此网址使用了一个通常用于网络浏览以外目的的端口.出于安全原因,Firefox 取消了该请求. Chrome 无 ...