2

私が指定した Select ステートメントに基づいて、データベース内の値を監視し続けるプログラムを開発する必要があります。

監視された値はいつでも変更でき、私のプログラムは、私が指定したselectステートメントの結果に基づいて変更を感知する必要があります

私のシステムには別の機能もあり、ユーザーは値を監視するだけでなく、それに取り組む必要があるため、TThread を使用して選択結果を監視したいと考えています。

Delphi XE2 で TThread を使用してそれを行う方法

VCLを使用しています...いいえ.Net

よろしく。

4

1 に答える 1

3

[編集]

回答が改善され、スレッドが継続的に実行され、「値を監視し続ける」ようになりました。

サンプルを作成してみましょう。

まず、新しい VCL アプリを作成します。1 つの TListBox コンポーネントと 2 つの TButton コンポーネントをフォームにドロップします。ボタン クリック ハンドラーを作成し、プライベート メソッドを 1 つ追加する必要があります。ユニット全体は次のようになります。

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 をコードで置き換えます:

ユニットユニット2;

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 スレッドを押すと実行が停止します。

次のことを考慮する必要があります。

  1. 値を監視する間隔を設定します。デフォルトは 1000 ミリ秒です。間隔プロパティを参照してください。

  2. Execute 内およびそれに関連するすべてのコード (DB アクセス コンポーネントを含む) は、スレッド保存する必要があります。

于 2012-07-10T07:52:19.360 に答える