> cca 20 000 recorda.
To nije nista, slobodno ih sve prevuci i filtriraj rucno (ili putem TDataset.Filter propertija).
> FIBPlus, mislim da nisu thread safe. baza je firebird
> u principu prikazuje rezultate queryja u db gridu.
To eventualno moze biti problem posto se sadrzaj vuce iz dataseta koji je u drugom threadu.
> Znam da pitam puno, ali može primjer kako bi mogao napisati taj tread?
Otprilike
Code:
TMyThread = class(TThread)
private
FDB: TDatabase;
FQuery: TQuery;
FEvent: TEvent;
FSQL: string;
procedure ProcessSQL;
protected
procedure Execute; override;
public
constructor Create;
destructor Destroy; override;
procedure ScheduleSQL(const ASQL: string);
function GetResQuery: TQuery;
procedure Finish;
end;
{ TMyThread }
constructor TMyThread.Create;
begin
inherited Create(False);
FEvent := TEvent.Create;
end;
destructor TMyThread.Destroy;
begin
FEvent.Free;
FDB.Free;
FQuery.Free;
inherited Destroy;
end;
procedure TMyThread.Execute;
begin
while not Terminated do
begin
if FEvent.WaitFor(INFINITE) = wrSignaled then
begin
FEvent.ResetEvent;
ProcessSQL;
end;
end;
end;
procedure TBackgroundProcessor.Finish;
begin
Terminate;
FEvent.SetEvent;
// Wait for thread to finish (but not indefinitelly) and release it.
if WaitForSingleObject(Handle, 1200) = WAIT_OBJECT_0 then
Free;
end;
procedure TMyThread.ProcessSQL;
begin
if FSQL = '' then
Exit;
FDB := TDatabase.Create; // Kod da se napravi db komponenta i poveze na bazu
FQuery := TQuery.Craete(FDB); // Kod da se napravi query i poveze na FDB
FQuery.SQL := FSQL;
FQuery.Execute;
while not FQuery.Eof do // Prevuci sve podatke
FQuery.Next;
PostMessage(Application.MainForm.Handle, WM_APP, 1, 0); // Signaliziramo da je kveri spreman
end;
procedure TMyThread.ScheduleSQL(const ASQL: string);
begin
FSQL := ASQL;
FEvent.SetEvent;
end;
function TMyThread.GetResQuery: TQuery;
begin
Result := FQuery;
FQuery := nil; // Da se vise ne moze koristiti iz ovog threada
end;
glavni thread/forma.
TfrmMain = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
FQuery: TQuery;
FMyThread: TMyThread;
public
procedure WMApp(var Message: TMessage); message WM_APP;
end;
TfrmMain.WMApp(var Message: TMessage); message WM_APP;
begin
FQuery := FMyThread.GetResQuery;
Datasource.DAtaset := FQuery;
DBGrid.Datasource := DataSource;
end;
procedure TfrmMain.FormCreate(Sender: TObject);
begin
FMyThread := TMyThread.Create;
end;
procedure TfrmMain.FormDestroy(Sender: TObject);
begin
FMyThread.Finish;
end;
A u OnChangu stavi FThread.ScheduleSQL('select * from tabela');
Ako ova varijanta (sa pravljenjem u jednom threadu a koriscenjem u drugom ne radi) onda vidi da kopiras podatke u neki pomocni dataset, tipa TClientDataset.