AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Threads mit Ereignissen

Ein Thema von Nersgatt · begonnen am 13. Okt 2011 · letzter Beitrag vom 17. Okt 2011
Antwort Antwort
Seite 1 von 3  1 23   
Benutzerbild von Nersgatt
Nersgatt

Registriert seit: 12. Sep 2008
Ort: Emlichheim
693 Beiträge
 
Delphi 10.1 Berlin Professional
 
#1

Threads mit Ereignissen

  Alt 13. Okt 2011, 12:23
Hallo,

ich habe ein Problem, dem ich nicht auf die Schliche komme. Ein Programm importiert eine große Menge Daten von einer Firebirddatenbank in eine andere Firebirddatenbank. Das wird in einem extra Thread erledigt. Der Mainthread stellt den Fortschritt dar (Progressbar, Statusmeldungen, Fehlermeldungen, etc).

Nun stürzt mir dieser Programmteil scheinbar zufällig an ganz verschiedenen Stellen mit der bekannten Meldung "Dieses Programm funktioniert nicht mehr..." ab. Wie komme ich dem auf die Schliche?

Ich hab so ein bisschen meine Kommunikation mit dem Mainthread in Verdacht. Die Threadklasse hat Ereignisse, auf die der Mainthread reagieren kann. So ein Ergeignis löse ich z.B. so aus:
Delphi-Quellcode:
procedure TImporter.EndImport;
begin
  if Assigned(FOnEndImport) then
    Synchronize(
      procedure
        begin
          FOnEndImport();
        end);
end;
Das heißt, ich rufe im Threadkontext (Threadklasse = TImporter) die Methode "EndImport" auf. So kann der Mainthread auf diese Ereignis reagieren. Das habe ich noch an weiteren Stellen, z.B. um eine Progressbar upzudaten.
Kann man das grundsätzlich so machen, oder gibts dabei Fallstricke, die ich nicht beachtet hab? Gibts bei den anonymen Methoden irgendwelche Gemeinheiten?

Danke!
Jens
Jens
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.674 Beiträge
 
Delphi 2007 Enterprise
 
#2

AW: Threads mit Ereignissen

  Alt 13. Okt 2011, 12:35
Hm, ich wäre da mit Messages ran gegangen, so dass die Threads so weit wie möglich entkoppelt sind. Aber rein prinzipiell sehe ich auch bei deiner jetzigen Variante - zumindest so isoliert - keine ernsten Schnitzer.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.395 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: Threads mit Ereignissen

  Alt 13. Okt 2011, 13:02
Bei mir sieht das im Prinzip so aus:
Delphi-Quellcode:
procedure TImporter.EndImport;
begin
  {unnötiges Synchronize vermeiden}
  if Assigned(FOnEndImport) then
    Synchronize(DoOnEndImport);
end;

procedure TImporter.DoOnEndImport;
begin
  {wird im Hauptthread ausgeführt,
   FOnImport könnte inzwischen durch den Hauptthread geändert sein}

  if Assigned(FOnEndImport) then
    FOnEndImport();
end;
Ich vermute den Fehler aber an anderer Stelle.
Jeder Thread benötigt eigene Datenbankverbindung.
Auf keinen Fall dürfen datensensitive Steuerelemente mit dieser Datenbankverbindung arbeiten.
Innerhalb des Threads:
- Exceptions müssen auf jeden Fall abgefangen und verarbeitet werden
- In OnError-Events keine Meldungen oder ähnliches.
- Die Datenbankkomponenten dürfen keine Meldungen anzeigen, den Cursor verändern oder ähnliches.

Geändert von Blup (14. Okt 2011 um 10:24 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Nersgatt
Nersgatt

Registriert seit: 12. Sep 2008
Ort: Emlichheim
693 Beiträge
 
Delphi 10.1 Berlin Professional
 
#4

AW: Threads mit Ereignissen

  Alt 13. Okt 2011, 13:14
Der Zugriff auf die Datenbank läuft über DBExpress. Der Thread bekommt eine komplett eigene Connection zu DB, die nur er benutzt. Das selbe gilt für den ganzen anderen DB-Krams (TSQLQueries, etc). Die werden im Thread dynamisch erstellt und freigegeben. Exceptions werden auch abgefangen. Auf diese Punkte hab ich großen Wert gelegt.

Ich hab mal sämlich Kommunikation mit dem Mainthread auskommentiert. Daran scheint es nicht zu liegen. Ich ermittle in eine bisschen anderen Richtung, denn manchmal läuft der Import problemlos durch (immer mit den selben Daten).

Der Import ist eigentlich zweigeteilt. Die Quelldatenbank wird als Zip-Datei heruntergeladen und dann auf dem CLientrechner entpackt (läuft im Mainthread). Dann wird eine Verbindung zu der gerade entpacken DB aufgebaut und die Daten daraus importiert (Import dann im Thread). Es scheint so, als träte der Fehler nur auf, wenn man die DB wirklich direkt vorher runtergeladen hat. Macht man erst den Download, beendet das Programm, startet es wieder und startet dann den Import, läuft es Fehlerfrei durch...

ich liebe solche Fehler einen Tag vorm Urlaub.
Jens
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#5

AW: Threads mit Ereignissen

  Alt 13. Okt 2011, 13:20
klingt nach einem Problem an das ich mich zu erinnern glaube, dass in meinem Fall ZipMaster noch etwas gesperrt hatte ....
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
CCRDude

Registriert seit: 9. Jun 2011
669 Beiträge
 
FreePascal / Lazarus
 
#6

AW: Threads mit Ereignissen

  Alt 13. Okt 2011, 13:24
Nenn es doch konkret... häufig wird bei Verwendung von TZipMaster nach Aufruf der Pack- oder Entpack-Methode nicht darauf gewartet, daß das Busy-Property wieder false wird.
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#7

AW: Threads mit Ereignissen

  Alt 13. Okt 2011, 13:26
Danke, hätte ich, ist nur schon ewig her dass ich das Teil verwenden musste ...
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Benutzerbild von Nersgatt
Nersgatt

Registriert seit: 12. Sep 2008
Ort: Emlichheim
693 Beiträge
 
Delphi 10.1 Berlin Professional
 
#8

AW: Threads mit Ereignissen

  Alt 13. Okt 2011, 13:42
Hm, scheinbar lässt sich in der Tat das Problem auf das Entpacken reduzieren. Kommentier ich das aus, läuft es immer durch.

Die Abfrage auf das Busy-Flag fehlte in der Tat. Aber trotzdem scheint es da noch ein Problem zu geben. Fällt jemandem etwas auf?

Delphi-Quellcode:
procedure TfrmImportPSM.UnzipFile(AFilename: String);
var
  zip: TZipMaster19;
begin

  DeleteFileWhenExist(ChangeFileExt(AFilename, '.fdb'));

  zip := TZipMaster19.Create(nil);
  try
    zip.ZipFileName := AFilename;
    zip.ExtrBaseDir := ExtractFilePath(AFilename);
    zip.Extract;
    while zip.Busy do
      application.ProcessMessages;

  finally
    zip.Free;
  end;

end;
Jens
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie
(Moderator)

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#9

AW: Threads mit Ereignissen

  Alt 13. Okt 2011, 14:20
Hat die Komponente kein Ereignis dafür? Wenn nicht und die Quellcodes zur Verfügung stehen, könnte es sich lohnen dieses selbst zu implementiere oder die Klasse entsprechend zu erweitern.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von Nersgatt
Nersgatt

Registriert seit: 12. Sep 2008
Ort: Emlichheim
693 Beiträge
 
Delphi 10.1 Berlin Professional
 
#10

AW: Threads mit Ereignissen

  Alt 13. Okt 2011, 15:12
Doch, es gibt ein OnStateChanged. Aber auch wenn ich hier auf die Beendigung warte, funktioniert es nicht. Es lässt sich definitiv auf das Entzippen reduzieren.
Hab nun auch die letzte Version von ZipMaster installiert, trotzdem keine Besserung. Dann hab ich mir dem ProcessMonitor mal verfolgt, was da geöffnet und geschlossen wird. So wie ich das sehe, wie die Datei nach dem entpacken ordentlich geschlossen.
Bin langsam mit meinem Latein am Ende, wo ich noch suchen könnte.
Jens
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23   

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 08:50 Uhr.
Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf