Delphi线程定时器 - -人生如歌- - 博客园
http://www.cnblogs.com/zhengwei0113/p/4192010.html

(*

  自己编写的线程计时器,没有采用消息机制,很有效

  Cobbler续写

  不用 TTimer 的原因:

  要说TTimer类的使用问题,先要说一下它响应用户定义的回调函数(OnTimer)的方法。
TTimer拥有一个HWnd类型的成员变量FWindowHandle,用于捕捉系统消息。
TTimer在Enable的情况下,每隔Interval时间,就抛一个系统消息WM_TIMER,FWindowHandle捕捉到这个消息后,
就会执行用户的回调函数,实现用户需要的功能。就是这个消息机制引发了下面两个问题: 问题1: 还不算严重,TTimer与系统共用一个消息队列,也就是说,在用户回调函数处理完之前,
所有的系统消息都处于阻塞状态,包括界面的更新的消息。
如果你的回调函数瞬间执行完毕那就一切看着还正常,如果你要执行一个复杂耗时的操作,
比如数据库查询什么的(万一遇到数据库联接不正常,等待20秒),
那你的界面就必死无疑,直到回调函数执行完。如果是后台系统还好,
要是给用户使用的就没法交待了。即使你在子线程里面使用也不会解决的。 问题2: 一般系统定义消息的优先级比用户定义消息的优先级要低。
在子线程中使用TTimer时,如果线程间通信也大量使用自定义消息,
并且用户定义自己的消息处理函数,那WM_TIMER经常就会被丢弃了,
计时器就彻底失效了。 摘抄自网络 *) unit UntThreadTimer; interface uses
Windows, Classes, Winapi.Messages; type
TTimerStatus = (TS_ENABLE, TS_CHANGEINTERVAL, TS_DISABLE, TS_SETONTIMER);
TThreadedTimer = class;
TTimerThread = class;
PTimerThread = ^TTimerThread; TTimerThread = class(TThread)
OwnerTimer: TThreadedTimer;
Interval: DWord;
Enabled: Boolean;
Status: TTimerStatus;
constructor Create(CreateSuspended: Boolean);
destructor Destroy; override;
procedure Execute; override;
procedure DoTimer;
end; TThreadedTimer = class(TComponent)
private
FHandle: THandle;
FEnabled: Boolean;
FInterval: DWord;
FOnTimer: TNotifyEvent;
FTimerThread: TTimerThread;
FThreadPriority: TThreadPriority;
protected
procedure UpdateTimer;
procedure SetEnabled(Value: Boolean);
procedure SetInterval(Value: DWord);
procedure SetOnTimer(Value: TNotifyEvent);
procedure Timer; dynamic;
public
constructor Create(AHandle: THandle; AOwner: TComponent);
destructor Destroy; override;
published
property Enabled: Boolean read FEnabled write SetEnabled default True;
property Interval: DWord read FInterval write SetInterval default ;
property OnTimer: TNotifyEvent read FOnTimer write SetOnTimer;
end; implementation procedure WakeupDownThrdproc(const evenFlag: Integer); stdcall;
begin end; { TTimerThread }
constructor TTimerThread.Create(CreateSuspended: Boolean);
begin
inherited Create(CreateSuspended);
Interval := ;
Enabled := False;
Status := TS_DISABLE;
end; destructor TTimerThread.Destroy;
begin
inherited;
end; procedure TTimerThread.Execute;
begin
inherited;
while not Terminated do
begin
// SleepEx(Interval, True);
if (not Terminated) and (Status = TS_ENABLE) then
Synchronize(DoTimer);
if Status <> TS_ENABLE then
begin
case Status of
TS_CHANGEINTERVAL:
begin
Status := TS_ENABLE;
SleepEx(, True);
end;
TS_DISABLE:
begin
Status := TS_ENABLE;
SleepEx(, True);
if not Terminated then
Suspend;
end;
TS_SETONTIMER:
begin
Status := TS_ENABLE;
end
else
Status := TS_ENABLE;
end;
end;
SleepEx(Interval, True);
end;
end; procedure TTimerThread.DoTimer;
begin
OwnerTimer.Timer;
end; { TThreadedTimer }
constructor TThreadedTimer.Create(AHandle: THandle; AOwner: TComponent);
begin
inherited Create(AOwner);
FHandle := AHandle;
FInterval := ;
FThreadPriority := tpNormal;
FTimerThread := TTimerThread.Create(True);
FTimerThread.OwnerTimer := self;
end; destructor TThreadedTimer.Destroy;
begin
inherited Destroy;
FTimerThread.Terminate;
QueueUserAPC(@WakeupDownThrdproc, FTimerThread.Handle, DWord(FTimerThread));
FTimerThread.Free;
end; procedure TThreadedTimer.UpdateTimer;
begin
if (FEnabled = False) then
begin
FTimerThread.OwnerTimer := self;
FTimerThread.Interval := FInterval;
FTimerThread.Priority := FThreadPriority;
FTimerThread.Resume;
end;
if (FEnabled = True) then
begin
QueueUserAPC(@WakeupDownThrdproc, FTimerThread.Handle, DWord(FTimerThread));
end;
end; procedure TThreadedTimer.SetEnabled(Value: Boolean);
begin
if Value <> FEnabled then
begin
FEnabled := Value;
if Value then
begin
FTimerThread.Status := TS_ENABLE;
FTimerThread.Resume;
end
else
begin
FTimerThread.Status := TS_DISABLE;
QueueUserAPC(@WakeupDownThrdproc, FTimerThread.Handle,
DWord(FTimerThread));
end;
end;
end; procedure TThreadedTimer.SetInterval(Value: DWord);
begin
if Value <> FInterval then
begin
if (not Enabled) then
begin
FInterval := Value;
FTimerThread.Interval := FInterval;
end
else
begin
FInterval := Value;
FTimerThread.Interval := FInterval;
FTimerThread.Status := TS_CHANGEINTERVAL;
QueueUserAPC(@WakeupDownThrdproc, FTimerThread.Handle,
DWord(FTimerThread));
end;
end;
end; procedure TThreadedTimer.SetOnTimer(Value: TNotifyEvent);
begin
FOnTimer := Value;
end; procedure TThreadedTimer.Timer;
var
Msg: TMessage;
begin
Msg.Msg := WM_USER + ;
// if Assigned(FOnTimer) then FOnTimer(Self);
SendMessage(FHandle, Msg.Msg, , );
end; end.

用法:

delphi新语法之泛型实现的对象池模板 - 咏南 delphi - 博客园--TThreadList;//对象池 中 对象 列表

http://www.cnblogs.com/hnxxcxg/archive/2013/07/15/3191622.html
数据模块池 - 咏南 delphi - 博客园
http://www.cnblogs.com/hnxxcxg/p/3619672.html

Delphi线程定时器TThreadedTimer及用法--还有TThreadList用法可以locklist的更多相关文章

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

    第六节: TList 与泛型   TList 是一个重要的容器,用途广泛,配合泛型,更是如虎添翼. 我们先来改进一下带泛型的 TList 基类,以便以后使用. 本例源码下载(delphi XE8版本) ...

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

    多线程的基本概念和Delphi线程对象Tthread介绍 作者:xiaoru    WIN 98/NT/2000/XP是个多任务操作系统,也就是:一个进程可以划分为多个线程,每个线程轮流占用CPU运行 ...

  3. TMsgThread, TCommThread -- 在delphi线程中实现消息循环

    http://delphi.cjcsoft.net//viewthread.php?tid=635 在delphi线程中实现消息循环 在delphi线程中实现消息循环 Delphi的TThread类使 ...

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

    在delphi线程中实现消息循环 在delphi线程中实现消息循环 Delphi的TThread类使用很方便,但是有时候我们需要在线程类中使用消息循环,delphi没有提供.   花了两天的事件研究了 ...

  5. Delphi maskedit控件的掩码含义及用法方法

    Delphi maskedit控件的掩码含义及用法方法   1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 2 ...

  6. delphi 线程教学第二节:在线程时空中操作界面(UI)

    第二节:在线程时空中操作界面(UI)   1.为什么要用 TThread ?   TThread 基于操作系统的线程函数封装,隐藏了诸多繁琐的细节. 适合于大部分情况多线程任务的实现.这个理由足够了吧 ...

  7. delphi 线程教学第一节:初识多线程

    第一节:初识多线程   1.为什么要学习多线程编程?   多线程(多个线程同时运行)编程,亦可称之为异步编程. 有了多线程,主界面才不会因为耗时代码而造成“假死“状态. 有了多线程,才能使多个任务同时 ...

  8. 线程中的WaitForSingleObject和Event的用法

    http://chinaxyw.iteye.com/blog/548622 首先介绍CreateEvent是创建windows事件的意思,作用主要用在判断线程退出,程锁定方面. CreateEvent ...

  9. python线程定时器Timer(32)

    相对前面几篇python线程内容而言,本片内容相对比较简单,定时器 – 顾名思义,必然用于定时任务. 一.线程定时器Timer原理 原理比较简单,指定时间间隔后启动线程!适用场景:完成定时任务,例如: ...

随机推荐

  1. 【非专业前端】使用vue2.5.17+element2.4.5

    开发工具:WebStorm 先搞好环境 可以看出,想安装@vue/cli需要node.js.先去下载安装好. 然后安装@vue/cli npm install -g @vue/clinpm insta ...

  2. JS模块化开发(四)——构建工具gulp

    gulp.js——基于流的自动化构建工具 步骤: 1. 全局安装 gulp: $ npm install --global gulp 2. 作为项目的开发依赖(devDependencies)安装: ...

  3. Redis的主从复制的原理介绍

    redis主从复制 和Mysql主从复制的原因一样,Redis虽然读取写入的速度都特别快,但是也会产生读压力特别大的情况.为了分担读压力,Redis支持主从复制,Redis的主从结构可以采用一主多从或 ...

  4. 关键字(5):cursor游标:(循环操作批量数据)

    declare   cursor stus_cur is select * from students;  --定义游标并且赋值(is 不能和cursor分开使用)    cur_stu studen ...

  5. 5.django学习模型

    ##Django Models ##编写models 1.在应用根目录下创建models.py并引入models模块,创建类,继承models.Model该类即是一张数据表 2.字段创建 ##映射数据 ...

  6. C++ MFC------ 快捷键

    创建快捷键 该文讲解如何给dialog的菜单或者按钮添加快捷键. 1.局部快捷键 点击控件,右键点“属性”,在属性Caption后添加&Key,例如: &Y,即通过按Alt+Y即可触发 ...

  7. mybatis无mapper.xml用法

    在datasource配置类上加上 @MapperScan("cn.x.x.dao")@Configuration <project xmlns="http://m ...

  8. nGrinder TestRunner DNS / sun.net.spi.nameservice.NameServiceDescriptor

    s ngrinder3.3控制台验证脚本报错 http://ngrinder.642.n7.nabble.com/ngrinder3-3-td1301.html 目前发现3.3版本在控制台校验脚本报错 ...

  9. MyBatis-SqlSessionFactory的创建

    Main 方法,mybatis 版本为 3.5.0 解析配置文件的所有信息,保存在 Configuration 中,返回包含 Configuration 的 DefaultSqlSession Map ...

  10. html(常用标签,标签分类),页面模板, CSS(css的三种引入方式),三种引入方式优先级

    HTML 标记语言为非编程语言负责完成页面的结构 组成: 标签:被<>包裹的由字母开头,可以结合合法字符( -|数字 ),能被浏览器解析的特殊符号,标签有头有尾 指令:被<>包 ...