2012-07-09 1 views
1

Мне нужно разработать программу для просмотра значений в базах данных на основе оператора Select, заданного мнойКак заставить TThread продолжать работать в фоновом режиме и показывать мне результат в Listbox?

Просмотренные значения могут быть изменены в любое время, и моя программа должна воспринимать изменения на основе результата операции выбора, которая дается мной

Я хочу посмотреть результат выбора с помощью TThread, потому что моя система также имеет другие функции, и пользователю нужно работать над ней не только для просмотра значений.

, как сделать это с помощью TThread в Delphi XE2

Я использую VCL ... нет .Net

С уважением.

+0

Из потока вызывается 'TThread.Synchronize' для обновления пользовательского интерфейса. Это запускает обновление кода в основном потоке пользовательского интерфейса. –

+2

С Delphi поставляется простая нить-приложение, которое очень хорошо показывает, как использовать Synchronize для обновления пользовательского интерфейса в основном потоке. – Andreas

+2

ОК. Итак, с какой частью задачи вы столкнулись? «Как это сделать» недостаточно конкретно. –

ответ

3

[Редактировать]

Улучшенный ответ, теперь нить работает непрерывно и "продолжайте наблюдать значения".

Давайте построим образец.

Сначала создайте новое приложение 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 прекращает выполнение.

Вы должны принять во внимание:

  1. Set Interval смотреть значения, по умолчанию 1000 мс, см интервал собственности;

  2. Весь ваш код (включая компоненты доступа DB) внутри Execute и связанный с ним должен быть нить-save.

+0

Что вы подразумеваете под словом «Весь ваш код (включая компоненты доступа к БД) внутри Execute и связанный с ним должен быть thread-save»? – user1512094

+0

Посмотрите здесь: http://en.wikipedia.org/wiki/Thread_safety – Marcodor

+0

Некоторые примечания об ADO: http://stackoverflow.com/questions/3266532/ok-to-use-tadoconnection-in-threads – Marcodor

 Смежные вопросы

  • Нет связанных вопросов^_^