Delphiindy线程控件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不会
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论