如何让TThread在后台继续工作,并在Listbox中向我显示结果



我必须开发一个程序,根据给出的Select语句来监视数据库中的值

监视的值可以随时更改,我的程序必须根据给出的select语句的结果来感知这些更改

我想通过使用TThread来查看选择结果,因为我的系统还有其他功能,用户不仅需要查看值,还需要对其进行操作。

如何在DelphiXE2中使用TThread

正在使用VCL。。。无.Net

谨致问候。

[Edit]

改进了答案,现在线程连续运行,并"不断观察值"。

让我们构建一个示例。

首先,创建新的VCL应用程序。在表单上放置一个TListBox和两个TButton组件。您需要编写按钮单击处理程序并添加一个私有方法。整个单元应该是这样的:

unit Unit1;
interface
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Unit2;
type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
    FCollector: TCollector;
    procedure OnCollect(S: TStrings);
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
  if Assigned(FCollector) then Exit;
  FCollector := TCollector.Create;
  FCollector.OnCollect := Self.OnCollect;
  FCollector.Start;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
  if not Assigned(FCollector) then Exit;
  FCollector.Terminate;
  FCollector := nil;
end;
procedure TForm1.OnCollect(S: TStrings);
begin
  ListBox1.Items.AddStrings(S);
end;
end.

接下来我们应该添加我们的线程,从菜单中选择:文件->新单元并替换为代码:

第二单元;

interface
uses
  System.Classes;
type
  TCollectEvent = procedure (S: TStrings) of object;
  TCollector = class(TThread)
  private
    { Private declarations }
    FTick: THandle;
    FItems: TStrings;
    FOnCollect: TCollectEvent;
    FInterval: Integer;
  protected
    procedure Execute; override;
    procedure DoCollect;
  public
    constructor Create;
    destructor Destroy; override;
    procedure Terminate;
    property Interval: Integer read FInterval write FInterval;
    property OnCollect: TCollectEvent read FOnCollect write FOnCollect;
  end;
implementation
uses Windows, SysUtils;
{ TCollector }
constructor TCollector.Create;
begin
  inherited Create(True);
  FreeOnTerminate := True;
  FInterval := 1000;
  FTick := CreateEvent(nil, True, False, nil);
end;
destructor TCollector.Destroy;
begin
  CloseHandle(FTick);
  inherited;
end;
procedure TCollector.DoCollect;
begin
  FOnCollect(FItems);
end;
procedure TCollector.Terminate;
begin
  inherited;
  SetEvent(FTick);
end;
procedure TCollector.Execute;
begin
  while not Terminated do
  begin
    if WaitForSingleObject(FTick, FInterval) = WAIT_TIMEOUT then
    begin
      FItems := TStringList.Create;
      try
        // Collect here items
        FItems.Add('Item ' + IntToStr(Random(100)));
        Synchronize(DoCollect);
      finally
        FItems.Free;
      end;
    end;
  end;
end;
end.

现在,当你按下按钮1时,你将收到来自组合中线程的项目。按下按钮2线程将停止执行。

你应该考虑:

  1. 将Interval设置为监视值,默认值为1000ms,请参阅Interval属性;

  2. Execute中的所有代码(包括DB访问组件)以及与之相关的代码都应该是线程保存的。

相关内容

最新更新