Delphi - Indy TIdThreadComponent 线程研究

Indy IdThreadComponent 线程研究

前几天在开发数据实时解析功能模块的时候,发现解析数据量巨大,特别耗时,程序一跑起来界面假死。

为了优化用户体验,采用了Indy 自带的IdThreadComponent控件,完美的解决了此问题。

下面就IdThreadComponent一些关键属性和方法做如下记录:

1:IdThreadComponent属性

这里主要记录一下Active、Priority和StopMode属性。

Active:默认False,当需要令IdThreadComponent控件生效时,置为True;

Priority:为避免线程之间相互冲突,选择Normal,让系统自带分配优先级;

StopMode:这里分为Terminate和Suspend两种,Terminate为强行终止,Suspend为延缓、等待终止。

2:IdThreadComponent方法

TIdThreadComponent用的是观察者模式,所有这里的事件都是回调事件。

一般比较耗时的操作放在OnRun中执行。

事件执行顺序如下:

On Before Execute;

On Before Run;

On Run; 

On Stopped;

On After Run;

On After Execute;

3:通过如下Demo进行说明

需要说明一下:

在线程里不可以直接操作界面上的控件,因为有时候控件被销毁了而线程还在运行,这时直接操作会抛AV异常,所以在TIdThreadComponent回调事件中,如果有使用到控件的,必须先做控件是否为空的判断。

界面如下:

代码如下:

unit uMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, RzButton, StdCtrls, RzEdit, IdBaseComponent, IdThreadComponent;

type
  TMainFrm = class(TForm)
    IDTrd: TIdThreadComponent;
    mmMsg: TRzMemo;
    btnStart: TRzBitBtn;
    btnStop: TRzBitBtn;
    btnTerminal: TRzBitBtn;
    procedure btnStartClick(Sender: TObject);
    procedure IDTrdRun(Sender: TIdCustomThreadComponent);
    procedure IDTrdBeforeExecute(Sender: TIdCustomThreadComponent);
    procedure IDTrdAfterExecute(Sender: TIdCustomThreadComponent);
    procedure btnStopClick(Sender: TObject);
    procedure btnTerminalClick(Sender: TObject);
    procedure IDTrdAfterRun(Sender: TIdCustomThreadComponent);
    procedure IDTrdBeforeRun(Sender: TIdCustomThreadComponent);
    procedure IDTrdStopped(Sender: TIdCustomThreadComponent);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  MainFrm: TMainFrm;

implementation

{$R *.dfm}

procedure TMainFrm.btnStartClick(Sender: TObject);
begin
  IDTrd.Active := True;
end;

procedure TMainFrm.IDTrdRun(Sender: TIdCustomThreadComponent);
var
  I: Integer;
begin
  for I := 1 to 100 do
  begin
    mmMsg.Lines.Add(IntToStr(I)); //模拟耗时操作
  end;
  //在线程里不可以直接操作界面控件,有时候控件被销毁了而线程还在运行,
  //此时就会报AV异常,
  //所以在TIdThreadComponent回调事件中有使用到控件的,必须添加控件是否为空判断
end;

procedure TMainFrm.IDTrdBeforeExecute(Sender: TIdCustomThreadComponent);
begin
  if Assigned(mmMsg) then
  begin
    mmMsg.Lines.Add('Before Execute');
  end;
end;

procedure TMainFrm.IDTrdAfterExecute(Sender: TIdCustomThreadComponent);
begin
  if Assigned(mmMsg) then
  begin
    mmMsg.Lines.Add('After Execute');
  end;
end;

procedure TMainFrm.btnStopClick(Sender: TObject);
begin
  IDTrd.Stop;
end;

procedure TMainFrm.btnTerminalClick(Sender: TObject);
begin
  IDTrd.Terminate;
end;

procedure TMainFrm.IDTrdAfterRun(Sender: TIdCustomThreadComponent);
begin
  if Assigned(mmMsg) then
  begin
    mmMsg.Lines.Add('After Run');
  end;
end;

procedure TMainFrm.IDTrdBeforeRun(Sender: TIdCustomThreadComponent);
begin
  if Assigned(mmMsg) then
  begin
    mmMsg.Lines.Add('Before Run');
  end;
end;

procedure TMainFrm.IDTrdStopped(Sender: TIdCustomThreadComponent);
begin
  if Assigned(mmMsg) then
  begin
    mmMsg.Lines.Add('On Stopped');
  end;
end;

end.

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

蝈蝈(GuoGuo)

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

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

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

打赏作者

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

抵扣说明:

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

余额充值