首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用TTimer和使用TThread有什么区别?

使用TTimer和使用TThread有什么区别?
EN

Stack Overflow用户
提问于 2015-09-15 08:06:42
回答 5查看 2.8K关注 0票数 6

我开发了一个连接到Server数据库并每1秒从表中读取一些数据的应用程序。

为此,我使用TTimer,但是数据库响应的延迟会影响我的应用程序性能。

我对Delphi中的TThread略知一二,我现在想知道的是使用TTimerTThread之间的区别?在这种情况下,使用TThread而不是TTimer对我的应用程序性能很有用吗?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2015-09-15 08:28:58

这两者之间的主要区别可以在它们的类定义中找到:

  • TTimer = class(TComponent)
  • TThread = class

虽然TTimer类扩展了TComponent并且是一个组件本身,但是TThread是一个扩展TObject的抽象类。

TThread公开静态方法(如TThread.Sleep )和名为Execute的特殊受保护方法,该方法必须在派生类中实现,才能执行所需的任务。TThread直接使用客户操作系统的进程和线程函数。

..。为此,我使用TTimer,但是数据库响应的延迟会影响应用程序的性能

之所以会发生这种情况,是因为TTimer对象的TTimer事件是在调用线程中执行的:当将TTimer组件放入表单并实现其OnTimer事件时,代码将在主线程中执行。

TThread方法更灵活:如果出于某种原因,代码必须在主线程中执行,则可以在线程的Execute方法中嵌套一个正弦化块

如果希望在一段时间间隔后以重复方式执行数据库请求,则最好考虑将TThreadTEvent对象结合使用。

使用TEvent定义类的示例

代码语言:javascript
复制
TMyThread = class(TThread)
  private
    FInterval: Integer;
    FWaitEvent: TEvent;
  protected
    procedure Execute; override;
    procedure TerminatedSet; override;
  public
    constructor Create(Interval: Cardinal; CreateSuspended: Boolean);
    destructor Destroy; override;
end;

已实现的类:

代码语言:javascript
复制
constructor TMyThread.Create(Interval: Cardinal; CreateSuspended: Boolean);
begin
  inherited Create(CreateSuspended);
  FInterval := Interval;
  FWaitEvent := TEvent.Create(nil, False, False, '');
end;

destructor TMyThread.Destroy;
begin
  FWaitEvent.Free;
  inherited;
end;

procedure TMyThread.TerminatedSet;
begin
  inherited;
  FWaitEvent.SetEvent;
end;

procedure TMyThread.Execute;
begin
  inherited;
  while not Terminated do begin
    //do your stuff

    //wait fo some amount of time before continue the execution
    if wrSignaled = FWaitEvent.WaitFor(FInterval) then
      Break;
  end;
end;

WaitFor对象上调用的FWaitEvent方法允许等待所需的时间。

线程的TerminatedSet方法的实现允许将FWaitEvent对象置于信号状态,然后在间隔过去之前退出线程。

票数 3
EN

Stack Overflow用户

发布于 2015-09-15 08:13:16

TTimer是一个基于消息的计时器.它将WM_TIMER消息发布到创建它的线程的消息队列中。您的数据库操作正在阻止该线程及时处理新消息。假设您的TTimer处于主UI线程中,这就是为什么您的应用程序性能受到影响的原因。将数据库操作移动到辅助线程可以防止主线程的消息循环被阻塞。

票数 3
EN

Stack Overflow用户

发布于 2015-09-15 09:16:15

这并不能具体解决你的问题,但正如对其他答案之一的评论中所指出的,按你所做的频率轮询一个数据库并不是一个好主意,特别是当其他用户试图访问它的时候。

当数据发生变化时,有多种方法从数据库服务器获得通知,而不需要不断轮询它们。这篇Embarcadero论文对各种DBMS的可用内容进行了非常有用的回顾:

28 %28FireDAC%29

如果您的Delphi版本包括FireDAC,您将从链接中看到,如果DBMS支持TFDEventAlerter,您可以使用TFDEventAlerter在服务器上接收数据更改通知。

如果您使用的是Interbase或Firebird (可能还有其他一些),则可以使用不需要FireDAC的替代Delphi组件,例如Interbase的IBExpress库中的TIBEventAlerter。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32580862

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档