delphi 同时更新表单中不同面板上的数据的最佳方法是什么?定时器/线程?

g6baxovj  于 2023-05-06  发布在  其他
关注(0)|答案(1)|浏览(172)

我在 Delphi 10.3中有一个应用程序,它有多个表单,所有表单都包含需要定期更新的不同数据。我喜欢在每个窗体中有一个计时器的想法,我可以控制每个面板的计时频率。每个表单都作为单独的pas文件存在,并作为子表单示例化到主表单中。
我越是深入研究,就越觉得同时拥有太多计时器是一种糟糕的做法。然后我就想到了线。
下面是我从另一个关于在线程中使用计时器的问题中找到的建议。我在所有其他窗体继承的baseform中创建了这个线程,它调用一个抽象方法来刷新该窗体示例。
这个方法对我的应用程序有帮助吗?还是只是使它更加复杂?我最好在主线程中使用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.

对于我可能错过的这种事情,有没有更好的标准?

atmip9wb

atmip9wb1#

我相信这个想法(Threads)会使你的编程更加复杂,如果你需要的是更新视觉元素,它不会有任何贡献。
可视化数据更新部分(非线程安全)应该在线程“外部”执行(使用Synchronize),因此如果线程的大部分工作都使用Synchronize(在主线程上)执行,则不存在时间增益。
我认为在这种情况下,你可以使用计时器。

相关问题