如何让TThread继续在后台工作,并在列表框中显示结果? [英] how to let the TThread to keep working in background and showing me the result in a Listbox?
问题描述
我必须开发一个程序,以根据我给出的Select语句继续监视数据库中的值
I have to develop a program to keep watching values in databases based on a Select statement given by me
可以随时更改监视值,并且我的程序必须根据我给出的select语句的结果来感知更改
the watched values can be changed at anytime and my program must sense the changes based on a result of the select statement which is given by me
我想使用TThread监视选择结果,因为我的系统还具有其他功能,用户不仅需要监视值,还需要对其进行处理.
i want to watch the select result by using TThread because my system is also has another features and the user need to work on it not only to watch values.
如何在Delphi XE2中使用TThread进行操作
how to do it using TThread in Delphi XE2
am使用VCL ...没有.Net
am using VCL...no .Net
致谢.
推荐答案
改进的答案,现在线程连续运行并保持观察值".
Improved answer, now thread runs continuously and "keep watching values".
让我们建立一个样本.
首先,创建新的VCL应用.在窗体上放置一个TListBox和两个TButton组件.您需要编写按钮单击处理程序并添加一个私有方法.整个单位应如下所示:
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:
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.
接下来,我们应该添加线程,从菜单中选择:File-> New unit,并替换为代码:
Next we should add our thread, select from menu: File -> New unit and replace with code:
unit Unit2;
unit 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时,您将从组合中的线程Items中接收.按下Button2线程停止执行.
Now, when you press Button1, you will receive from thread Items in your combo. Pressing Button2 thread stops executing.
您应该考虑:
-
将时间间隔"设置为监视值,默认值为1000ms,请参见时间间隔属性;
Set Interval to watch values, default is 1000ms, see interval property;
您在Execute内和与之相关的所有代码(包括数据库访问组件)都应该是线程保存的.
All your code (include DB access components) inside Execute and related to it should be thread-save.
这篇关于如何让TThread继续在后台工作,并在列表框中显示结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!