不管什么语言,编写线程函数或者架构总是一项基本功,对于Delphi语言也不例外,Delphi原生提供有线程对象TThread,直接使用TThread也没有问题,当然对于高版本的Delphi 也还提供了TTask等多任务对象,包括匿名线程等等,但是本文将详细介绍Delphi中大名鼎鼎的Indy中的线程控件:TIdThreadComponent。
TIdThreadComponent 使用非常方便,只需要就简单的书写事件函数即可。
一、控件的属性:
二、控件事件
三、控件方法:
四、详细说明
如果要执行一个函数在线程中运行,也就是说不凝滞UI。就简单的书写 TOnRun 事件函数即可。例如我们期望执行如下功能:
procedure TForm5.THRun(Sender: TIdThreadComponent);
begin
//(Sender as TIdThreadComponent).Stop;
(Sender as TIdThreadComponent).Tag := Random(1000);
TThread.Queue(nil,
procedure
begin
memo1.Lines.Add('*** Run *** ' + ' ' + FormatDateTime('hh:mm:ss',Now));
end);
sleep(2000);
//raise Exception.Create('This is an error message');
end;
上述函数功能就是生成一个随机数,将其赋值给TIdThreadComponent 控件的 Tag 属性,然后同步UI显示出字符串 *** Run *** 和时间。然后模拟线程运行占用2秒时间 Sleep(2000)。
如果需要运行线程,那么只需执行面的方法即可:
IdThreadComponent.Start;
重点注意:
如果直接这样,那么线程函数将会不断循环执行,也就是说,线程执行完成后,又开始从头执行,一直不断。我们大多数情况下并不期望线程循环执行,我们只期望线程执行一次就可以了,后面如果需要我们再次运行。如果不需要循环,那就记得在 TOnRun 事件函数中打开函数体中的第一条注释语句:(Sender as TIdThreadComponent).Stop; 这样线程就只执行一次就结束了!
停止线程执行命令:
IdThreadComponent.Stop;
注意:
发送了 Stop 命令后,线程执行是否能够立即停止,需要根据线程任务的实际情况来说,如果线程没有配合 Stop 命令,就像本例上述 TOnRun 函数提事件,就不能立即停止,而是要等待延时2秒后。
发送了 IdThreadComponent.Start 命令后,各个事件函数的执行顺序如下:
如果 属性 Loop := False。则表现结果如下:
- OnBeforeExecute
- OnBeforeRun
- *** OnRun *** 这个才是线程体
- OnAfterRun
- OnCleanup
- OnBeforeRun
- *** OnRun *** 这个才是线程体
- OnAfterRun
- OnCleanup
- OnBeforeRun
- *** OnRun *** 这个才是线程体
- OnAfterRun
- OnCleanup
- .....
- OnAfterExecute
- OnTerminate
如果 属性 Loop := True。则表现结果如下:
- OnBeforeExecute
- OnBeforeRun
- *** OnRun *** 这个才是线程体
- *** OnRun *** 这个才是线程体
- *** OnRun *** 这个才是线程体
- OnAfterRun
- OnCleanup
- OnAfterExecute
- OnTerminate
如果线程出现异常,则各个事件函数的顺序如下:
- OnBeforeExecute
- OnBeforeRun
- *** OnRun *** 这个才是线程体
- OnHandleRunException //VHandled := True;
- OnAfterRun
- OnCleanup
- OnAfterExecute
- OnTerminate
或者:
- OnBeforeExecute
- OnBeforeRun
- *** OnRun *** 这个才是线程体
- OnHandleRunException //VHandled := False;
- OnAfterRun
- OnCleanup
- OnAfterExecute
- OnException
- OnTerminate
五、重点属性
属性 | 值 | 说明 |
Active | False | 切记不要设置成 True,会导致程序异常 |
Loop | True / False | 表示线程体执行是否触发 BeforeRun 和 AfterRun 事件。True每次都触发,False 只触发一次 |
Prioroity | ![]() | 表示线程的优先级: tpIdle :线程仅在系统空闲时执行。Windows 不会中断其他线程来执行具有 tpIdle 优先级的线程。 tpLowest :线程的优先级比正常低两级。 tpLower :线程的优先级比正常值低一级。 tpHigher :线程的优先级比正常高一级。 tpHighest :线程的优先级比正常高两级。 tpTimeCritical :线程的优先级最高。 |
SopMode | ![]() | 直接设置成 smTerminate |
如果需要在线程执行前处理一些事情,可以根据Loop的情况,然后书写 OnBeforeExecute 或者OnBeforeRun。OnBeforeExecute 始终只执行一次。
如果需要处理线程中的异常,请书写:OnHandleRunException 或者 OnException 事件函数。
示例程序:
2025-04-22
如果在线程执行期间需要埋点尽快结束线程,代码如下:
if FStopRunning then
begin
FRanse_Thread.Stop;
Exit;
end;
切记需要这样埋点才可以尽快退出,否则一定要等待线程执行完成才会退出!