![]() |
Datenbank: Firebird • Version: 2.1 • Zugriff über: Zeos 7
[gelöst] Applikation friert ein bei Datenbankzugriff trotz Thread
Hallo...
Mein Kollege kam zu mir weil seine Datenbankanwendung zyklisch sekundenweise einfriert. Beim debuggen hab ich dann schnell herausgefunden, dass die Datenbankabfragen die Ursache dafür sind. Klarer Fall. Das muss gethreadded werden. Doch auch mit Thread friert meine kleine Sandbox ein. Wie kann das denn angehen? Bissl (unfertiger) Code:
Delphi-Quellcode:
type
TUpdater = class(TThread) private FCnx: TZConnection; FQry: TZQuery; FCS: TCriticalSection; FRepository: CRepository; FObjects: TObjectList; FTable: String; FKlausel: String; destructor destroy; protected procedure Execute; override; public constructor create(CreateSuspended: Boolean); end;
Delphi-Quellcode:
procedure TUpdater.Execute;
var Instance: TKMicsRepository; begin CoInitialize(nil); // Hab ich nach der Forensuche eingebaut - hat nichts bewirkt FQry.SQL.Clear; FQry.SQL.Add('SELECT * FROM '+FTable); if FKlausel <> '' then FQry.SQL.Add('WHERE '+FKlausel); // Alles mögliche auskommentiert - friert trotzdem immernoch kurz ein... // if Assigned(FCS) then // FCS.Enter; try FQry.Open; // FObjects.Clear; while not FQry.Eof do // ... und zwar genau hier begin // Instance:=CRepository(FRepository).Create; // Instance.readValue(FQry.Fields); // FObjects.Add(Instance); FQry.Next; end; finally // if Assigned(FCS) then // FCS.Leave; end; FQry.Close; FCnx.Disconnect; CoUnInitialize; Self.Terminate; end; constructor TUpdater.create(CreateSuspended: Boolean); begin inherited Create(CreateSuspended); FCnx:=TZConnection.Create(nil); FCnx.Protocol:= 'firebird-2.1'; FCnx.HostName:= '192.168.200.5'; FCnx.Database:= 'c:\firebird\test2.fdb'; FCnx.User:= 'sysdba'; FCnx.Password:= 'masterkey'; FCnx.Properties.Clear; {..} FQry:=TZQuery.Create(nil); FQry.Properties.Clear; {..} FQry.Connection:=FCnx; end; destructor TUpdater.destroy; begin freeAndNil(FCnx); freeAndNil(FQry); inherited Destroy; end;
Delphi-Quellcode:
Jemand noch ne Idee was das sein kann?
procedure TCachingTable.refresh;
var Updater: TUpdater; begin Updater:=TUpdater.Create(true); Updater.FreeOnTerminate:=true; Updater.FCS:=FCS; Updater.FTable:=FTable; Updater.FKlausel:=FKlausel; Updater.FRepository:=FRepository; Updater.FObjects:=FObjects; Updater.Resume; while not Updater.Finished do Application.ProcessMessages; if Assigned(doUpdate) then doUpdate(self); end; Gruß, Toni |
AW: Applikation friert ein bei Datenbankzugriff trotz Thread
Zitat:
|
AW: Applikation friert ein bei Datenbankzugriff trotz Thread
Naja, er soll ja ausschließlich die Usereingaben weiter ausführen. Ich hielt das für zweckmäßig. zu syncen gibts da nix. Es geht während er läuft (also zwischen Resume und Terminate) nix rein und nix raus.
[Edit] Es geht mir nur darum während eines Datenbankzugriffs im Frontend Scrollbars bedienen zu können. In meiner Sandbox hab ich eine Combobox mit 200 Einträgen, die ich mit der Maus hoch und runter scrolle. [/Edit] |
AW: Applikation friert ein bei Datenbankzugriff trotz Thread
Es geht darum, daß man in fremden Threads auf keine VCL-Dinge zugreift (außer man synchronisiert diese Zugriffe in den Hauptthread)
Und ProcessMessages hat in Threads sowieso nichts zu suchen. |
AW: Applikation friert ein bei Datenbankzugriff trotz Thread
Delphi-Quellcode:
das lass mal besser weg und reagiere auf das onThreadTerminate-Ereignis
while not Updater.Finished do
Application.ProcessMessages; |
AW: Applikation friert ein bei Datenbankzugriff trotz Thread
Hi,
du gehst die Datenmenge ja einmal komplett durch? Naja ich würde nach dem Open in dem Fall erstmal ein First machen vll hilft das? Amsonsten fallen mir nur noch sowas wie Events ein die dran hängen oder sowas wie CalcFields, weiss leider nicht wie dein FQry aussieht.
Delphi-Quellcode:
while not FQry.Eof do// ... und zwar genau hier
begin // Instance:=CRepository(FRepository).Create; // Instance.readValue(FQry.Fields); // FObjects.Add(Instance); FQry.Next; end; |
AW: Applikation friert ein bei Datenbankzugriff trotz Thread
Guten Morgen.
@himitsu: Das ist nicht IM Thread sondern eher außen herum in der GUI. Hab das gestern nicht mehr geschafft auszuprobieren. Aber mit onTerminate klappts. Vielen Dank für den Hinweis. Unter D7 war das nie ein Problem. Ist das neu? Gruß, Toni |
AW: Applikation friert ein bei Datenbankzugriff trotz Thread
Du darfst bei Threads nicht wie üblich die (bzw. bestimmte) Felder im constructor initialisieren, sondern du darsft das erst in Execute. Hier geht es hauptsächlich um die DB-Kompos.
VErsuch dir folgende Strucktur anzugewöhnen:
Delphi-Quellcode:
Edit: Und die letzten 4 Zeilen in Refresh nimmst du bitte auch raus und löst das anders!
procedure Tupdater.execute;
begin ConInitialize(nil); myConnection:=TxyzConnection.Create(...); myQuery:=... try eigentlicher_Thread_execute; finally myQuery.free; myConnection.free; coUninitialize; end; end; procedure Tupdater.eigentlicher_thread_execute; begin ... end; Es gibt z.B. das Ereignis onTerminate, dass du zuweisen kannst (auf doUpdate). |
AW: Applikation friert ein bei Datenbankzugriff trotz Thread
Zitat:
Toni |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:05 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz