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 := to 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.

作者:Jeremy.Wu
  出处:https://www.cnblogs.com/jeremywucnblog/

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

Delphi - Indy TIdThreadComponent 线程研究的更多相关文章

  1. Delphi indy线程控件TIdThreadComponent的使用

    当程序需要做耗时操作,例如访问数据库获取较多的数据.获取大文件MD5.网络访问数据量比较大.界面需要频繁刷新等等,都可以用线程来解决界面卡顿的问题,从而优化用户体验. 在知道TIdThreadComp ...

  2. Delphi中的线程类 - TThread详解

    Delphi中的线程类 - TThread详解 2011年06月27日 星期一 20:28 Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大多数Delphi书藉都有说到,但基本 ...

  3. Delphi中的线程类(转)

    Delphi中的线程类 (转) Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大多数Delphi书藉都有说到,但基本上都是对 TThread类的几个成员作一简单介绍,再说明一下 ...

  4. [delphi]indy idhttp post方法

    网易 博客 LOFTCam-用心创造滤镜 LOFTER-最美图片社交APP 送20张免费照片冲印 > 注册登录  加关注 techiepc的博客 万事如意 首页 日志 LOFTER 相册 音乐 ...

  5. [Sciter系列] MFC下的Sciter–5.Sciter中GUI线程研究

    [Sciter系列] MFC下的Sciter–5.Sciter中GUI线程研究,目前MFC存在问题,win32没问题. 本系列文章的目的就是一步步构建出一个功能可用,接口基本完善的基于MFC框架的Sc ...

  6. 在Delphi中创建线程,请一定使用BeginThread()代替CreateThread()创建线程!(更好的管理异常)

    在Delphi中创建线程,请一定使用BeginThread()代替CreateThread()创建线程! 如果直接使用Win32的API函数CreateThread()创建多个线程,也是可以创建的.但 ...

  7. Delphi Indy IDHttp 403 forbidden

    http://hbk777.blog.163.com/blog/static/6058086200681594333361/ Delphi Indy IDHttp 403 forbidden 2006 ...

  8. delphi 读网页线程TReadHtmlThread

    读网页,通常是一个耗时操作.故把读网页放入线程是显得比较重要了. 本例用改进后的 TIdhttpEx 加上线程来实现读网页. 它的父类TSimpleThread 在此 本例程源码在此 源码中包含了所有 ...

  9. Delphi 中 COM 实现研究手记(一)

    前言 前些日子用 Delphi 写了一个 Windows 外壳扩展程序,大家知道 Windows 外壳扩展实际上就是 COM 的一种应用 -- Shell COM,虽然整个程序写得还算比较顺利,但写完 ...

随机推荐

  1. UTF—8与UTF—8(无bom)格式

    BOM——Byte Order Mark,就是字节序标记 在UCS 编码中有一个叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的编码是FEFF.而FFFE在U ...

  2. supervisor指南

    1 安装 yum install -y supervisor 如果提示没有这个安装包,则需要添加epel源 wget -O /etc/yum.repos.d/epel.repo http://mirr ...

  3. 【iOS】No suitable application records found

    昨天提交 Apple 审核时遇到这个问题,如图: 原来是还没在 iTunes Connect 创建 APP ... 一时着急大意了…… 后来想想还真是脑子一时没反应过来……

  4. 【Python-Django后端开发】配置静态文件详解!!!

    配置前端静态文件 1. 准备静态文件 2. 指定静态文件加载路径 STATIC_URL = '/static/' # 配置静态文件加载路径 STATICFILES_DIRS = [os.path.jo ...

  5. ORACLE 的CONNECT BY、START WITH,CONNECT_BY_ROOT、CONNECT_BY_ISLEAF、SYS_CONNECT_BY_PATH,LEVEL的使用(Hierarchical query-层次查询)

    如果表中存在层次数据,则可以使用层次化查询子句查询出表中行记录之间的层次关系基本语法: START WITH <condition1> CONNECT BY [ NOCYCLE ] < ...

  6. .net core使用ocelot---第一篇 简单使用

    简介原文地址 接下来你会学习,基于asp.net core 用Ocelot实现一个简单的API网关.或许你会疑问什么是API网关,我们先看下面的截图 API网关是访问你系统的入口,它包括很多东西,比如 ...

  7. 超全的 Vue 开源项目合集,签收一下

    超全的 Vue 开源项目合集,签收一下 xiaoge2016 前端开发 1周前 作者:xiaoge2016 链接: https://my.oschina.net/u/3018050/blog/2049 ...

  8. Spark 系列(八)—— Spark SQL 之 DataFrame 和 Dataset

    一.Spark SQL简介 Spark SQL 是 Spark 中的一个子模块,主要用于操作结构化数据.它具有以下特点: 能够将 SQL 查询与 Spark 程序无缝混合,允许您使用 SQL 或 Da ...

  9. linux后台运行的几种方式

    1.nohup将程序以忽略挂起信号的方式运行起来 补充说明nohup命令 可以将程序以忽略挂起信号的方式运行起来,被运行的程序的输出信息将不会显示到终端.无论是否将 nohup 命令的输出重定向到终端 ...

  10. Gitment评论插件的使用

    前言 继上一篇的 GitPages部署自己的网站 现在开始添加博客的评论插件Gitment.这里的话我是使用hexo添加gitment插件,如果不是使用hexo,请到官网指定这里. 开始 第一步 注册 ...