• Delphi


    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回调事件中,如果有使用到控件的,必须先做控件是否为空的判断。

    界面如下:

    代码如下:

      1 unit uMain;
      2 
      3 interface
      4 
      5 uses
      6   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      7   Dialogs, RzButton, StdCtrls, RzEdit, IdBaseComponent, IdThreadComponent;
      8 
      9 type
     10   TMainFrm = class(TForm)
     11     IDTrd: TIdThreadComponent;
     12     mmMsg: TRzMemo;
     13     btnStart: TRzBitBtn;
     14     btnStop: TRzBitBtn;
     15     btnTerminal: TRzBitBtn;
     16     procedure btnStartClick(Sender: TObject);
     17     procedure IDTrdRun(Sender: TIdCustomThreadComponent);
     18     procedure IDTrdBeforeExecute(Sender: TIdCustomThreadComponent);
     19     procedure IDTrdAfterExecute(Sender: TIdCustomThreadComponent);
     20     procedure btnStopClick(Sender: TObject);
     21     procedure btnTerminalClick(Sender: TObject);
     22     procedure IDTrdAfterRun(Sender: TIdCustomThreadComponent);
     23     procedure IDTrdBeforeRun(Sender: TIdCustomThreadComponent);
     24     procedure IDTrdStopped(Sender: TIdCustomThreadComponent);
     25   private
     26     { Private declarations }
     27   public
     28     { Public declarations }
     29   end;
     30 
     31 var
     32   MainFrm: TMainFrm;
     33 
     34 implementation
     35 
     36 {$R *.dfm}
     37 
     38 procedure TMainFrm.btnStartClick(Sender: TObject);
     39 begin
     40   IDTrd.Active := True;
     41 end;
     42 
     43 procedure TMainFrm.IDTrdRun(Sender: TIdCustomThreadComponent);
     44 var
     45   I: Integer;
     46 begin
     47   for I := 1 to 100 do
     48   begin
     49     mmMsg.Lines.Add(IntToStr(I)); //模拟耗时操作
     50   end;
     51   //在线程里不可以直接操作界面控件,有时候控件被销毁了而线程还在运行,
     52   //此时就会报AV异常,
     53   //所以在TIdThreadComponent回调事件中有使用到控件的,必须添加控件是否为空判断
     54 end;
     55 
     56 procedure TMainFrm.IDTrdBeforeExecute(Sender: TIdCustomThreadComponent);
     57 begin
     58   if Assigned(mmMsg) then
     59   begin
     60     mmMsg.Lines.Add('Before Execute');
     61   end;
     62 end;
     63 
     64 procedure TMainFrm.IDTrdAfterExecute(Sender: TIdCustomThreadComponent);
     65 begin
     66   if Assigned(mmMsg) then
     67   begin
     68     mmMsg.Lines.Add('After Execute');
     69   end;
     70 end;
     71 
     72 procedure TMainFrm.btnStopClick(Sender: TObject);
     73 begin
     74   IDTrd.Stop;
     75 end;
     76 
     77 procedure TMainFrm.btnTerminalClick(Sender: TObject);
     78 begin
     79   IDTrd.Terminate;
     80 end;
     81 
     82 procedure TMainFrm.IDTrdAfterRun(Sender: TIdCustomThreadComponent);
     83 begin
     84   if Assigned(mmMsg) then
     85   begin
     86     mmMsg.Lines.Add('After Run');
     87   end;
     88 end;
     89 
     90 procedure TMainFrm.IDTrdBeforeRun(Sender: TIdCustomThreadComponent);
     91 begin
     92   if Assigned(mmMsg) then
     93   begin
     94     mmMsg.Lines.Add('Before Run');
     95   end;
     96 end;
     97 
     98 procedure TMainFrm.IDTrdStopped(Sender: TIdCustomThreadComponent);
     99 begin
    100   if Assigned(mmMsg) then
    101   begin
    102     mmMsg.Lines.Add('On Stopped');
    103   end;
    104 end;
    105 
    106 end.

      作者:Jeremy.Wu
      出处:https://www.cnblogs.com/jeremywucnblog/
      本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    继续聊WPF
    窥探Swift之别具一格的Struct和Class
    窥探Swift之类的继承与类的访问权限
    iOS开发之地图与定位
    iOS开发之WebView
    iOS开发之版本控制(SVN)
    iOS开发之抽屉效果实现
    iOS开发之调用系统打电话发短信接口以及程序内发短信
    转:GitHub 万星推荐成长技术清单
    vmware漏洞之四:简评USE-AFTER-SILENCE: EXPLOITING A QUIETLY PATCHED UAF IN VMWARE
  • 原文地址:https://www.cnblogs.com/jeremywucnblog/p/11428598.html
Copyright © 2020-2023  润新知