我开发了一个连接到Server数据库并每1秒从表中读取一些数据的应用程序。
为此,我使用TTimer,但是数据库响应的延迟会影响我的应用程序性能。
我对Delphi中的TThread略知一二,我现在想知道的是使用TTimer和TThread之间的区别?在这种情况下,使用TThread而不是TTimer对我的应用程序性能很有用吗?
发布于 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方法中嵌套一个正弦化块。
如果希望在一段时间间隔后以重复方式执行数据库请求,则最好考虑将TThread与TEvent对象结合使用。
使用TEvent定义类的示例
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;已实现的类:
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对象置于信号状态,然后在间隔过去之前退出线程。
发布于 2015-09-15 08:13:16
TTimer是一个基于消息的计时器.它将WM_TIMER消息发布到创建它的线程的消息队列中。您的数据库操作正在阻止该线程及时处理新消息。假设您的TTimer处于主UI线程中,这就是为什么您的应用程序性能受到影响的原因。将数据库操作移动到辅助线程可以防止主线程的消息循环被阻塞。
发布于 2015-09-15 09:16:15
这并不能具体解决你的问题,但正如对其他答案之一的评论中所指出的,按你所做的频率轮询一个数据库并不是一个好主意,特别是当其他用户试图访问它的时候。
当数据发生变化时,有多种方法从数据库服务器获得通知,而不需要不断轮询它们。这篇Embarcadero论文对各种DBMS的可用内容进行了非常有用的回顾:
28 %28FireDAC%29
如果您的Delphi版本包括FireDAC,您将从链接中看到,如果DBMS支持TFDEventAlerter,您可以使用TFDEventAlerter在服务器上接收数据更改通知。
如果您使用的是Interbase或Firebird (可能还有其他一些),则可以使用不需要FireDAC的替代Delphi组件,例如Interbase的IBExpress库中的TIBEventAlerter。
https://stackoverflow.com/questions/32580862
复制相似问题