AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Thread Query keep it simple ABER ...

Ein Thema von cramer · begonnen am 8. Apr 2015 · letzter Beitrag vom 10. Apr 2015
Antwort Antwort
Benutzerbild von cramer
cramer

Registriert seit: 23. Jun 2004
Ort: Velbert (NRW)
93 Beiträge
 
Delphi 2006 Enterprise
 
#1

Thread Query keep it simple ABER ...

  Alt 8. Apr 2015, 20:41
Delphi-Version: 2006
Hallo,
mein 1. Versuch, den Querypart in einem Thread laufen zu lassen, um bei langen Abfragen
1. die Abfrage beenden zu können und
2. "die Anwendung reagiert nicht mehr" zu vermeiden.

Das ganze läuft mit IBObjects Komponenten und das Ergebnis wird in einem cxGrid angezeigt.

DB -> TiboDatabase -> TiboTransaction -> TiboQuery -> TDataSource -> TcxGridDBTableView

Es funktioniert alles ohne Probleme. Nur beim Programmende gibt immer Fehler 1400 "Ungültiges Fensterhandle", wenn vorher eine Query über den Thread gelaufen ist.

Bleibt möglicherweise die Verbindung "FQuery := aQuery", nach dem der Thread weg ist, bestehen und zeigt ins Nirvana?
Code:
type
   TiboqThread = class( TThread )
   private
      FQuery    : TiboQuery;
      FErrorCode : integer;
      FErrorText : string;
   public
      constructor Create( AQuery : TiboQuery );
      destructor Destroy; override;
      procedure  Execute; override;
      procedure  ClearError;
      procedure  SendError;
   end; { type }

constructor TiboQThread.Create( aQuery : TiboQuery );
begin
   inherited Create( True );
   FQuery := aQuery;
end;

procedure TiboQThread.ClearError;
begin
   LastErrCode := 0;
   LastErrText := '';
end;

procedure TiboQThread.SendError;
begin
   LastErrCode := FErrorCode;
   LastErrText := FErrorText;
end;

procedure TiboQThread.Execute;
var i : integer;
begin
   inherited;
   try
      Synchronize( ClearError );
      FQuery.Open;
   except
      on E : Exception do begin
         FErrorCode := 4313; // ERROR_DATABASE_FAILURE;
         FErrorText := 'Query-Thread:' + E.ClassName + ' - ' + E.Message;
         Synchronize( SendError );
      end;
   end;
end;

destructor TiboQThread.Destroy;
begin
   FQuery := nil;
   inherited;
end;

// Main
// ...
IBQ1.Active := False;
IBQ1.SQL.Text := tmpSql;
// IBQ1.Active := True;
// Try it via Thread
tQ := TiboqThread.create( IBQ1 );
tQ.FreeOnTerminate := False;
tQ.Resume;
while ( WaitForSingleObject( tQ.Handle, 100 ) = WAIT_TIMEOUT ) and
      ( A_Halt.Tag = 0 )
do begin
   Application.ProcessMessages;
end;
if LastErrCode = 0 then begin
   // Alles OK
end else begin
   FehlerAusgabe1( LastErrText );
end;
tQ.Free;
// ...
Ausschnitt aus dem Bugreport
Code:
exception class  : EOSError
exception message : System Error. Code: 1400. Ungültiges Fensterhandle.

main thread ($8b0):
0045ff80 +070 TEST.exe SysUtils                       RaiseLastOSError
0045ff09 +005 TEST.exe SysUtils                       RaiseLastOSError
004bb551 +031 TEST.exe Controls                       TWinControl.DestroyWindowHandle
004b9e0b +05f TEST.exe Controls                       TWinControl.Destroy
004c0ba5 +01d TEST.exe Controls                       TCustomControl.Destroy
0054b8e4 +020 TEST.exe cxControls            1987  +2 TcxSizeGrip.Destroy
00404710 +008 TEST.exe System                  48  +0 TObject.Free
00460630 +008 TEST.exe SysUtils                       FreeAndNil
0054c60d +021 TEST.exe cxControls            2507  +5 TcxControl.DestroyScrollBars
0054bc65 +019 TEST.exe cxControls            2127  +2 TcxControl.Destroy
0070423c +01c TEST.exe cxGridCustomView      4296  +3 TcxGridSite.Destroy
00404710 +008 TEST.exe System                  48  +0 TObject.Free
00460630 +008 TEST.exe SysUtils                       FreeAndNil
00706c6e +006 TEST.exe cxGridCustomView      6071  +1 TcxCustomGridViewInfo.DestroySite
00706a4c +010 TEST.exe cxGridCustomView      5975  +1 TcxCustomGridViewInfo.Destroy
006f2b24 +020 TEST.exe cxGridCustomTableView 12424  +2 TcxCustomGridTableViewInfo.Destroy
Erfahrung ist etwas, daß man erst bekommt, kurz nachdem man es dringend gebraucht hätte.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
35.205 Beiträge
 
Delphi 10.3 Rio
 
#2

AW: Thread Query keep it simple ABER ...

  Alt 8. Apr 2015, 20:59
Die VCL ist nicht threadsave.
Wenn also das Grid auf die Änderungen des Query reagiert, dann kann das nette Effekte haben.

* Query synchronisiert abhängen, solange der Thread etwas macht
* oder das Grid sperren (synchronisiertes DisableControls), solange der Thread etwas macht, und hoffen das Grid beachtet das wirklich komplett.

PS: Ich hoffe deine Connection ist auch threadsave. (vermutlich nicht, also nicht, daß gleichzeitig in einem anderen Thread/Hauptthread was damit gemacht wird)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
Benutzerbild von cramer
cramer

Registriert seit: 23. Jun 2004
Ort: Velbert (NRW)
93 Beiträge
 
Delphi 2006 Enterprise
 
#3

AW: Thread Query keep it simple ABER ...

  Alt 9. Apr 2015, 10:58
Danke für den Tip, ich warte ja in dem HauptThread auf das Ende des QueryThreads und mache dort zumindest nix Vordergründiges.

Es scheint aber so zu sein, wie Du es vermutet hast, das Grid reagiert im Hintergrund auf Änderungen in der Query.

Ich habe es daher vorher getrennt und hinterher wieder verbunden.
Der Spuk mit dem Error-1400 hat zumindest bei meinen Tests jetzt ein Ende gefunden.
Code:
// --------------
   ibds1.DataSet := nil;
   gridV1.DataController.DataSource := nil;
// --------------
tQ := TiboqThread.create( IBQ1 );
tQ.FreeOnTerminate := true;
tQ.Resume;
while ( WaitForSingleObject( tQ.Handle, 100 ) = WAIT_TIMEOUT ) and
      ( A_Halt.Tag = 0 )
do begin
  Application.ProcessMessages;
end;
if LastErrCode = 0 then begin
   // Alles OK
// --------------
   ibds1.DataSet := IBQ1;
   gridV1.DataController.DataSource := IBDS1;
// --------------
   GridV1.ClearItems;
   GridV1.DataController.CreateAllItems;
end else begin
   FehlerAusgabe1( LastErrText );
end;
tQ.Free;
Erfahrung ist etwas, daß man erst bekommt, kurz nachdem man es dringend gebraucht hätte.
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.124 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#4

AW: Thread Query keep it simple ABER ...

  Alt 9. Apr 2015, 11:15
Doofe Frage: Wofür soll der Thread gut sein, wenn du eh auf den Thread wartest?
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
3.935 Beiträge
 
Delphi 10.3 Rio
 
#5

AW: Thread Query keep it simple ABER ...

  Alt 9. Apr 2015, 12:28
Doofe Frage: Wofür soll der Thread gut sein, wenn du eh auf den Thread wartest?
Delphi-Quellcode:
while ( WaitForSingleObject( tQ.Handle, 100 ) = WAIT_TIMEOUT ) and
       ( A_Halt.Tag = 0 )
 do begin
   Application.ProcessMessages;
 end;
Damit der Mainthread weiter laufen kann und die "Reagiert nicht" Meldung nicht kommt, würde ich mal vermuten...
  Mit Zitat antworten Zitat
Benutzerbild von cramer
cramer

Registriert seit: 23. Jun 2004
Ort: Velbert (NRW)
93 Beiträge
 
Delphi 2006 Enterprise
 
#6

AW: Thread Query keep it simple ABER ...

  Alt 10. Apr 2015, 11:00
Stand doch im 1. Beitrag.
Hallo,
mein 1. Versuch, den Querypart in einem Thread laufen zu lassen, um bei langen Abfragen
1. die Abfrage beenden zu können und
2. "die Anwendung reagiert nicht mehr" zu vermeiden.
Erfahrung ist etwas, daß man erst bekommt, kurz nachdem man es dringend gebraucht hätte.
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:53 Uhr.
Powered by vBulletin® Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2019 by Daniel R. Wolf