Hallo,
ich habe das Problem, dass einige Ereignisse einfach verschluckt werden.
Ich habe 5 Threads die parallel etwas aus einer Datenbank laden. An sich kein Problem, aber manchmal wird er nicht fertig. Also einige Threads melden sie wären fertig, aber andere wieder melden dies nicht.
So sieht mein Thread aus:
Delphi-Quellcode:
type
TDatenbankLadenThread = class(TThread)
private
FListe: TZeilenListe;
FDatenbank: TDatenbank;
FOnFin: TNotifyEvent;
FArbeit: Boolean;
procedure DoFin;
function GibListe: TListe;
protected
procedure Execute; override;
public
property Zeilenliste : TZeilenListe read FListe write FListe;
property Datenbank : TDatenbank read FDatenbank write FDatenbank;
property Arbeitet : Boolean read FArbeit write FArbeit;
property Liste : TListe read GibListe;
property OnFinished : TNotifyEvent read FOnFin write FOnFin;
end;
procedure TDatenbankLadenThread.DoFin;
begin
if Assigned(FOnFin) then
FOnFin(Self);
end;
procedure TDatenbankLadenThread.Execute;
begin
while not Terminated do
begin
if Assigned(FListe) and Assigned(FDatenbank) and FArbeit then
begin
FListe.LadeAusDatenbank(FDatenbank);
FArbeit := False;
//Sleep(Random(1000) + 1000);
Synchronize(DoFin);
end;
Suspend;
end;
end;
Das klappt auch manchmal, aber manchmal ruft er nicht "FOnFin(Self)" auf. Deshalb bekomme ich dann nicht mit, dass er fertig geladen hat und dann war es dass.
Delphi-Quellcode:
function TDatenbankLader.LadeAusDatenbank(
const AListen: TListen) : Boolean;
{$IFDEF Threads}
var
Liste : TListe;
{$ENDIF}
begin
FListen := AListen;
Result := True;
try
[...]
// Dann die Threads starten
// ABER zuerst alle auf arbeitend setzen!
FLog.Add(DateTimeToStr(Now) + '
// StrtThrds');
for Liste
in AListen
do
begin
FLog.Add(DateTimeToStr(Now) + '
// StrtThrd: ' + ListeToName(Liste) + '
:: +Arbeitet');
FThreads[Liste].Arbeitet := True;
end;
// Dann die Datenbank "sperren"
FDatenbank.BeginTransaction;
for Liste
in AListen
do
begin
FLog.Add(DateTimeToStr(Now) + '
// StrtThrd: ' + ListeToName(Liste) + '
:: +Resume');
FThreads[Liste].Resume;
end;
FLog.SaveToFile(ExtractFilePath(ParamStr(0)) + '
log.txt');
except
on E :
Exception do
begin
LibMessageBox(
nil,
'
Ein Fehler ist aufgetreten',
'
Beim Laden der Datenbank ist ein Fehler aufgetreten! Bitte melden Sie ihn den Liberate Support.' + #13#10 + '
Fehlerklasse: ' + E.ClassName + #13#10 + '
Fehlertext: ' + #13#10 + E.
Message,
[mbOK],
dtFehler);
Result := False;
end;
end;
end;
procedure TDatenbankLader.ThreadFinished(Sender: TObject);
begin
FLog.Add(DateTimeToStr(Now) + '
// Thrd fin: ' + ListeToName((Sender
as TDatenbankLadenThread).Liste) + '
:: WrkCnt: ' + IntToStr(FThreads.ArbeitetAnzahl));
FLog.SaveToFile(ExtractFilePath(ParamStr(0)) + '
log.txt');
DoProgress(VORHERIGE_SCHRITTE + FThreads.ArbeitetAnzahl(False));
if FThreads.ArbeitetAnzahl = 0
then
begin
// Die Datenbank kann wieder "entsperrt" werden
FDatenbank.Commit;
Verknuepfe;
end;
end;
[edit]Achso wenn ich Prozesspriorität verringere, dann ist die Wahrscheinlichkeit höher das alles klappt.[/edit]
MfG
xZise