我在 Delphi 10.3 中有一个应用程序,它有多种形式,所有形式都包含需要定期更新的不同数据。我喜欢在每种形式中都有一个计时器的想法,我可以控制它为每个面板关闭的频率。每个表单都作为一个单独的 pas 文件存在,并作为孩子实例化到主表单中。
我研究得越多,就越觉得一次拥有太多计时器是一种不好的做法。于是我开始思考线程的想法。
以下是我从另一个关于在线程中使用计时器的问题中找到的建议。我在我所有其他表单继承的基本表单中创建这个线程,它调用一个抽象方法来刷新该表单实例。
这种方法对我的申请有帮助还是只会让申请变得更复杂?我最好只在主线程中使用 1 个计时器来刷新数据?
unit TimerThread;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TRefreshMethod = procedure of object;
type
TTimerThread = class(TThread)
private
FTickEvent: THandle;
Interval:Integer;
protected
ARefreshMethod: TRefreshMethod;
procedure Execute; override;
public
constructor Create(CreateSuspended: Boolean);
constructor CreateThreadTimer(CreateSuspended: Boolean; TimerInterval:Integer; RefreshMethod: TRefreshMethod = nil);
destructor Destroy; override;
procedure FinishThreadExecution;
end;
implementation
constructor TTimerThread.Create(CreateSuspended: Boolean);
begin
inherited;
FreeOnTerminate := True;
FTickEvent := CreateEvent(nil, True, False, nil);
end;
constructor TTimerThread.CreateThreadTimer(CreateSuspended: Boolean; TimerInterval:Integer; RefreshMethod: TRefreshMethod = nil);
begin
Create(CreateSuspended);
self.Interval := TimerInterval;
ARefreshMethod := RefreshMethod;
FreeOnTerminate := True;
FTickEvent := CreateEvent(nil, True, False, nil);
end;
destructor TTimerThread.Destroy;
begin
CloseHandle(FTickEvent);
inherited;
end;
procedure TTimerThread.FinishThreadExecution;
begin
Terminate;
SetEvent(FTickEvent);
end;
procedure TTimerThread.Execute;
begin
while not Terminated do
begin
if WaitForSingleObject(FTickEvent, Interval) = WAIT_TIMEOUT then
begin
Synchronize(procedure
begin
ARefreshMethod;
end
);
end;
end;
end;
end.
对于这种我可能会错过的东西,有没有更好的标准?
我相信这个想法(Threads)使您的编程更加复杂,如果您需要更新视觉元素,则不会做出任何贡献。
视觉数据更新部分(非线程安全)应该在线程“外部”执行(使用 Synchronize),因此如果线程的大部分工作是使用 Synchronize(在主线程上)执行的,则可以节省时间不存在。
我认为对于这种情况你可以使用定时器。