Delphi 线程Timer (TThreadTimer)

delphi 自带的Timer控件,使用方便,但它的 OnTimer 事件是在主线程中引发的。

如果在事件中执行较耗时的代码,会引起主界面假死。故实现一个线程的Timer就有必要了。

TThreadTimer 基于 TSimpleThread 继承而来。

本例源码下载

unit uThreadTimer;

interface

uses
  uSimpleThread;

type

  TThreadTimer = class; // 提前申明 TThreadTimer 是一个类

  TOnThreadTimer = procedure(Sender: TThreadTimer) of object;
  // 此处就可以引用 TThreadTimer,这种写法避免将 Sender 写为 TObject;
  // 为什么要写这个 sender ,主要是为了区别是谁引发了事件,并且 sender 上可以带参数
  // 方便进一步使用

  TThreadTimer = Class(TSimpleThread)
  private
    FInterval: Cardinal;
    FOnThreadTimer: TOnThreadTimer;

    procedure CountTimer;
    procedure DoCountTimer;
    procedure SetInterval(val: Cardinal);
    procedure SetOnThreadTimer(val: TOnThreadTimer);

    procedure DoOnThreadTimer; // 请学习此写法

  public
    constructor Create(AAllowActiveX: Boolean = false); // AAlowActiveX 在父类中有说明
    procedure StartThread; override; // 重载父类的 StartThread
    property Interval: Cardinal read FInterval write SetInterval default 1000;

    // 这个 default 1000 是给人看的,不会产生实际作用。
    // 故还需要在 Create 事件中指定 FInterval:=1000;
    // 如果可视化控件的 published 块中,此值会显示在属性编辑框中

    property OnThreadTimer: TOnThreadTimer read FOnThreadTimer write SetOnThreadTimer;

  End;

implementation

{ TThreadTimer }

procedure TThreadTimer.CountTimer;
begin
  ExeProcInThread(DoCountTimer);
  // 将 DoCountTimer 置入线程中去执行
  // 这是 TSimpleThread 的用法
end;

constructor TThreadTimer.Create(AAllowActiveX: Boolean);
begin
  inherited Create(AAllowActiveX);
  FInterval := 1000; // 默认间隔时间为 1 秒
end;

procedure TThreadTimer.DoCountTimer;
begin

  if WaitStop then // 这是父类的一个属性,表示线程现在需要停止了。
    exit;

  SleepExceptStopped(FInterval); // sleep 指定的时间,如果中途接到退出指令,则马上响应。
  // 父类中有源码,可看一看

  if not WaitStop then
  begin
    DoOnThreadTimer; // 引发时间到事件
  end;

  CountTimer; // 再次在线程中执行 DoCountTimer;
  // 父类已经设计好了,就这样简单地调用,即可实现在线程中执行本过程,但又不会引起“递归”

end;

procedure TThreadTimer.DoOnThreadTimer;
begin
  if Assigned(FOnThreadTimer) then
    FOnThreadTimer(Self);
  // 把这句写为一个过程,看似啰嗦,但为了程序可读性,是值得的。
end;

procedure TThreadTimer.StartThread;
begin
  inherited;
  CountTimer; // 启动计时
end;

procedure TThreadTimer.SetInterval(val: Cardinal);
begin
  FInterval := val;
end;

procedure TThreadTimer.SetOnThreadTimer(val: TOnThreadTimer);
begin
  FOnThreadTimer := val;
end;

end.

uThreadTimer.pas

附:delphi 进阶基础技能说明

http://www.cnblogs.com/lackey/p/5411389.html

时间: 2024-08-26 04:21:18

Delphi 线程Timer (TThreadTimer)的相关文章

TMsgThread, TCommThread -- 在delphi线程中实现消息循环(105篇博客,好多研究消息的文章)

在delphi线程中实现消息循环 在delphi线程中实现消息循环 Delphi的TThread类使用很方便,但是有时候我们需要在线程类中使用消息循环,delphi没有提供. 花了两天的事件研究了一下win32的消息系统,写了一个线程内消息循环的测试. 但是没有具体应用过,贴出来给有这方面需求的DFW参考一下.希望大家和我讨论. {----------------------------------------------------------------------------- Unit

delphi 线程教学第六节:TList与泛型

第六节: TList 与泛型 TList 是一个重要的容器,用途广泛,配合泛型,更是如虎添翼. 我们先来改进一下带泛型的 TList 基类,以便以后使用. 本例源码下载(delphi XE8版本): FooList.Zip unit uFooList; interface uses   Generics.Collections; type   TFooList <T>= class(TList<T>)   private     procedure FreeAllItems;   

多线程的基本概念和Delphi线程对象Tthread介绍

多线程的基本概念和Delphi线程对象Tthread介绍 作者:xiaoru WIN 98/NT/2000/XP是个多任务操作系统,也就是:一个进程可以划分为多个线程,每个线程轮流占用CPU运行时间和资源,或者说,把CPU 时间划成片,每个片分给不同的线程,这样,每个线程轮流的“挂起”和“唤醒”,由于时间片很小,给人的感觉是同时运行的. 多线程带来如下好处: 1)避免瓶颈: 2)并行操作: 3)提高效率:多线程的两个概念: 1) 进程:也称任务,程序载入内存,并分配资源,称为“一个进程”. 注意

在delphi线程中实现消息循环

http://delphi.cjcsoft.net//viewthread.php?tid=635 在delphi线程中实现消息循环 Delphi的TThread类使用很方便,但是有时候我们需要在线程类中使用消息循环,delphi没有提供. 花了两天的事件研究了一下win32的消息系统,写了一个线程内消息循环的测试. 但是没有具体应用过,贴出来给有这方面需求的DFW参考一下.希望大家和我讨论. {--------------------------------------------------

Delphi线程类 DIY(把类指针作为参数传进去,就可以执行类里面的方法啦)

Delphi 封装了一个很强大的线程类 TThread, 我们也自己动手制作一个简单的线程类 首先Type一个类 [delphi] view plain copy type TwwThread = class constructor Create; overload; destructor Destroy; override; private m_hThread: THandle;     //线程 m_ThreadID : TThreadID; public procedure Execute

Delphi线程的终止

当线程对象的Execute()执行完毕的时候,我们就认为此线程终止了.这时候,它会调用Delphi的一个标准例程EndThread(),这个例程再调用API函数ExitThread().由ExitThread()来清除线程所占用的栈. 当结束使用TThread对象的时候,应该确保已经把这个Object Pascal对象从内存中清除了.这才能确保所有内存占有都释放掉,尽管在进程终止时候会自动清除所有的线程对象,但是及时清除已经不再使用的对象,可以使内存的使用效率提高.利用将FreeOnTermin

Delphi线程池

unit uThreadPool; {   aPool.AddRequest(TMyRequest.Create(RequestParam1, RequestParam2, ...)); } interfaceuses  Windows,  Classes; // 是否记录日志// {$DEFINE NOLOGS} type  TCriticalSection = class(TObject)  protected    FSection: TRTLCriticalSection;  publi

Delphi 线程同步技术(转)

上次跟大家分享了线程的标准代码,其实在线程的使用中最重要的是线程的同步问题,如果你在使用线程后,发现你的界面经常被卡死,或者无法显示出来,显示混乱,你的使用的变量值老是不按预想的变化,结果往往出乎意料,那么你很有可能是忽略了线程同步的问题. 当有多个线程的时候,经常需要去同步这些线程以访问同一个数据或资源.例如,假设有一个程序,其中一个线程用于把文件读到内存,而另一个线程用于统计文件中的字符数.当然,在把整个文件调入内存之前,统计它的计数是没有意义的.但是,由于每个操作都有自己的 线程,操作系统

DELPHI线程例子-FC

{优秀的数据库应用应当充分考虑数据库访问的速度问题.通常可以通过优化数据库.优化 查询语句.分页查询等途径收到明显的效果.即使是这样,也不可避免地会在查询时闪现一个带有 SQL符号的沙漏,即鼠标变成了查询等待.最可怜的是用户,他(她)在此时只能无奈地等待.遇到急性子的,干脆在此时尝试 Windows中的其它应用程序,结果致使你的数据库应用显示一大片白色的窗口.真是无奈! 本文将以简单的例子告诉你如何实现线程查询.还等什么,赶快打开Delphi对照着下面的完整源代码试试吧. 在查询时能够做别的事情