Hallo Ihr alle,
ich wollte euch einmal mitteilen, wie dermaßen wichtig der richtige Gebrauch von try...finally-Blöcken seien kann. Bei mir im Programm sind beim Öffnen eines Dialoges plötzlich Zugriffsverletzungen aufgetreten.
Aber erstens nur auf einem System, auf dem BDS2006 nicht installiert ist - in der
IDE hat sich nichts getan, daher war debuggen nicht möglich und außerdem nur manchmal. Zunächst unerklärlich. Bis ich dahinter gekommen bin, dass sie immer dann auftreten, wenn ich vorher eine bestimmte Aktion gemacht habe.
Nach stundenlanger (ich habe seit heute Nachmittag 15 Uhr danach gesucht) Suche habe ich folgendes böses Stück Code gefunden:
Delphi-Quellcode:
ADODataSet := pLogicDataModule.GetADODataSet('SELECT ID FROM MD_InvoiceRules WHERE Active = 1 ORDER BY Mandator', true);
try
ProgressDialog := TJvProgressDialog.Create(NIL);
ProgressDialog.ScreenPosition := poMainFormCenter;
ProgressDialog.Caption := 'Rechnungserstellung';
ProgressDialog.Text := 'Verarbeite Regeln (insgesamt '+IntToStr(ADODataSet.RecordCount)+')';
ProgressDialog.Show;
ProgressDialog.Position := 0;
ProgressDialog.Min := 0;
ProgressDialog.Max := ADODataSet.RecordCount;
ProgressDialog.ShowCancel := False;
while not ADODataSet.Eof do
begin
ProcessInvoiceRule(ADODataSet.FieldByName('ID').AsInteger, AccountingPeriod);
ADODataSet.Next;
ProgressDialog.Position := ProgressDialog.Position+1;
end;
finally
ProgressDialog.Free;
ADODataSet.Free;
end;
Ich bin davon ausgegangen, dass dieser Progress-Dialog wohl keinen Schaden anrichten wird. Pustekuchen! Irgendwas hat er bewirkt. Ich denke, dass das ADODataSet nicht zerstört wurde, was dann irgendwann (immernoch unerklärlich
) zu Schutzverletzungen geführt hat.
Eine Änderung in folgendes, hat den Fehler eliminiert:
Delphi-Quellcode:
ADODataSet := pLogicDataModule.GetADODataSet('SELECT ID FROM MD_InvoiceRules WHERE Active = 1 ORDER BY Mandator', true);
try
ProgressDialog := TJvProgressDialog.Create(NIL);
try
ProgressDialog.ScreenPosition := poMainFormCenter;
ProgressDialog.Caption := 'Rechnungserstellung';
ProgressDialog.Text := 'Verarbeite Regeln (insgesamt '+IntToStr(ADODataSet.RecordCount)+')';
ProgressDialog.Show;
ProgressDialog.Position := 0;
ProgressDialog.Min := 0;
ProgressDialog.Max := ADODataSet.RecordCount;
ProgressDialog.ShowCancel := False;
while not ADODataSet.Eof do
begin
ProcessInvoiceRule(ADODataSet.FieldByName('ID').AsInteger, AccountingPeriod);
ADODataSet.Next;
ProgressDialog.Position := ProgressDialog.Position+1;
end;
ProgressDialog.Hide;
finally
ProgressDialog.Free;
end;
finally
ADODataSet.Free;
end;
Eines habe ich daraus gelernt: Spare nicht noch einmal an Try-Finally-Blöcken.
Das wollte ich einfach mal erzählt haben
Viele Grüße,
Dominik