【Delphi】详谈Indy中的线程控件:TIdThreadComponent

        不管什么语言,编写线程函数或者架构总是一项基本功,对于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。则表现结果如下:

  1. OnBeforeExecute
  2. OnBeforeRun
  3. *** OnRun *** 这个才是线程体
  4. OnAfterRun
  5. OnCleanup
  6. OnBeforeRun
  7. *** OnRun *** 这个才是线程体
  8. OnAfterRun
  9. OnCleanup
  10. OnBeforeRun
  11. *** OnRun *** 这个才是线程体
  12. OnAfterRun
  13. OnCleanup
  14. .....
  15. OnAfterExecute
  16. OnTerminate

如果 属性 Loop := True。则表现结果如下:

  1. OnBeforeExecute
  2. OnBeforeRun
  3. *** OnRun *** 这个才是线程体
  4. *** OnRun *** 这个才是线程体
  5. *** OnRun *** 这个才是线程体
  6. OnAfterRun
  7. OnCleanup
  8. OnAfterExecute
  9. OnTerminate

如果线程出现异常,则各个事件函数的顺序如下:

  1. OnBeforeExecute
  2. OnBeforeRun
  3. *** OnRun *** 这个才是线程体
  4. OnHandleRunException    //VHandled := True;
  5. OnAfterRun
  6. OnCleanup
  7. OnAfterExecute
  8. OnTerminate

或者:

  1. OnBeforeExecute
  2. OnBeforeRun
  3. *** OnRun *** 这个才是线程体
  4. OnHandleRunException    //VHandled := False;
  5. OnAfterRun
  6. OnCleanup
  7. OnAfterExecute
  8. OnException 
  9. OnTerminate

五、重点属性

属性说明
ActiveFalse切记不要设置成 True,会导致程序异常
LoopTrue / False表示线程体执行是否触发 BeforeRun 和 AfterRun 事件。True每次都触发,False 只触发一次
Prioroity

表示线程的优先级:

tpIdle :线程仅在系统空闲时执行。Windows 不会中断其他线程来执行具有 tpIdle 优先级的线程。

tpLowest :线程的优先级比正常低两级。

tpLower  :线程的优先级比正常值低一级。
tpNormal :线程的优先级正常。

tpHigher :线程的优先级比正常高一级。

tpHighest :线程的优先级比正常高两级。

tpTimeCritical  :线程的优先级最高。

SopMode直接设置成 smTerminate

如果需要在线程执行前处理一些事情,可以根据Loop的情况,然后书写 OnBeforeExecute 或者OnBeforeRun。OnBeforeExecute 始终只执行一次。

如果需要处理线程中的异常,请书写:OnHandleRunException 或者 OnException 事件函数。

示例程序:

2025-04-22 

如果在线程执行期间需要埋点尽快结束线程,代码如下:

if FStopRunning then
     begin
       FRanse_Thread.Stop;
       Exit;
     end;

切记需要这样埋点才可以尽快退出,否则一定要等待线程执行完成才会退出!

源代码及可执行文件下载!

使用TIdAntiFreeze对抗“冻结”   Indy使用一个特殊的组TIdAntiFreeze来透明地解决客户程序用户界面“冻结”的问题。TIdAntiFreeze在Indy内部定时中断对栈的调用,并在中断期间调用Application.ProcessMessages方法处理消息,而外部的Indy调用继续保存阻塞状态,就好像TIdAntiFreeze对象不存在一样。你只要在程序中的任意地方添加一个TIdAntiFreeze对象,就能在客户程序中利用到阻塞式Socket的所有优点而避开它的一些显著缺点。   Indy使用了线程技术   阻塞式Socekt通常都采用线程技术,Indy也是如此。从最底层开始,Indy的设计都是线程化的。因此用Indy创建服务器和客户程序跟在Unix下十分相似,并且Delphi的快速开发环境和Indy对WinSock的良好封装使得应用程序创建更加容易。   Indy服务器模型   一个典型的Unix服务器有一个或多个监听进程,它们不停地监听进入的客户连接请求。对于每一个需要服务的客户,都fork一个新进程来处理该客户的所有事务。这样一个进程只处理一个客户连接,编程就变得十分容易。   Indy服务器工作原理同Unix服务器十分类似,只是Windows不像Unix那样支持fork,而是支持线程,因此Indy服务器为每一个客户连接分配一个线程。   图1显示了Indy服务器的工作原理。Indy服务器组创建一个同应用程序主线程分离的监听线程来监听客户连接请求,对于接受的每一个客户,都创建一个新的线程来为该客户提供服务,所有与这一客户相关的事务都由该线程来处理。   使用组TIdThreadMgrPool,Indy还支持线程池。   线程与Indy客户程序   Indy客户端组并未使用线程。但是在一些高级的客户程序中,程序员可以在自定义的线程中使用Indy客户端组,以使用户界面更加友好。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海纳老吴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值