[Редактировать]
Улучшенный ответ, теперь нить работает непрерывно и "продолжайте наблюдать значения".
Давайте построим образец.
Сначала создайте новое приложение 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.
Далее мы должны добавить нашу нить, выберите из меню: Файл -> Новый блок и заменить код:
блок unit2;
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.
Теперь, когда вы нажимаете Button1, вы будете получать из темы в своей комбинации. Нажатие кнопки Button2 прекращает выполнение.
Вы должны принять во внимание:
Set Interval смотреть значения, по умолчанию 1000 мс, см интервал собственности;
Весь ваш код (включая компоненты доступа DB) внутри Execute и связанный с ним должен быть нить-save.
Из потока вызывается 'TThread.Synchronize' для обновления пользовательского интерфейса. Это запускает обновление кода в основном потоке пользовательского интерфейса. –
С Delphi поставляется простая нить-приложение, которое очень хорошо показывает, как использовать Synchronize для обновления пользовательского интерфейса в основном потоке. – Andreas
ОК. Итак, с какой частью задачи вы столкнулись? «Как это сделать» недостаточно конкретно. –