Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>[Edit]</p> <p>Improved answer, now thread runs continuously and "keep watching values".</p> <p>Let's build a sample.</p> <p>First, Create new VCL app. Drop on the form one TListBox and two TButton component. You need to write button click handlers and add one private method. Entire unit should look like this:</p> <pre><code>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. </code></pre> <p>Next we should add our thread, select from menu: File -> New unit and replace with code:</p> <p>unit Unit2;</p> <pre><code>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. </code></pre> <p>Now, when you press Button1, you will receive from thread Items in your combo. Pressing Button2 thread stops executing.</p> <p>You should take in account:</p> <ol> <li><p>Set Interval to watch values, default is 1000ms, see interval property;</p></li> <li><p>All your code (include DB access components) inside Execute and related to it should be thread-save.</p></li> </ol>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload