Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.142 Beiträge
 
Delphi 12 Athens
 
#2

AW: Execption innerhalb AnonymousThread behandeln

  Alt 30. Sep 2014, 04:57
Eigentlich sollte doch klar sein, wie man das macht?

Zugriffe auf die VCL müssen immer synchronisiert werden, also wieso wird das in der Exceptionbehandlung nicht gemacht?



TThread besitzt standardmäßig keinerlei Exception-Behandlung Auswertung.

Eine Behandlung ist drin, da Exceptions, welche bis ins System durchrauschen, den Prozess abschießen.
Exceptions im TThread.Execute werden abgefangen und sind über TThread.FatalException auswertbar, aber das muß man selber machen. (z.B. im TThread.OnTerminate)


Entweder du synchronisierst in deinem Try-Except die VCL-Zugriffe,
oder du läßt dein Try-Except komplett weg und benutzt das Try-Except der RTL, indem du z.B. ein OnTerminate implementierst und da anhängst.
Der Vorteil am OnTerminate ist, daß die RTL diesen Aufruf bereits in den MainThread synchronisiert.


Delphi-Quellcode:
type
  TMyThreadHelper = class abstract
    class procedure DoTerminate(Sender: TObject);
  end;

class procedure TMyThreadHelper.DoTerminate(Sender: TObject);
begin
  if Assigned(TThread(Sender).FatalException) then
    if TThread(Sender).FatalException is TDSRestProtocolException then
      HandleRestException(DataModule1.DSRestConnection1, 'Get Gruppen error', Exception(TThread(Sender).FatalException))
    else
      //ShowMessageFmt('Fehler: %s, [Exception(TThread(Sender).FatalException).Message]);
      //Application.HandleException(TThread(Sender).FatalException);
      ShowException(TThread(Sender).FatalException, nil); // such dir was aus
end;

with TThread.CreateAnonymousThread(
  procedure
  var
    LDataSetList: TFDJSONDataSets;
  begin
    LDataSetList := DataModule1.ServerMethods1Client.GetGruppen;
    UpdateGruppenNames(LDataSetList);
  end) do
begin
  OnTerminate := TMyThreadHelper.DoTerminate;
  Start;{TThread}
end;
Alternativ natürlich nicht ohne die Synchronisierung.
Eventuell auch nur um das ShowMessage, wenn das HandleRestException threadsave ist.
Delphi-Quellcode:
except
  on E: Exception do // alternativ ginge auch ein var E: TObject; und E := ExceptObject;
    TThread.Synchronize(TThread.CurrentThread,
      procedure
      begin
        if E is TDSRestProtocolException then
          HandleRestException(DataModule1.DSRestConnection1, 'Get Gruppen error', Exception(E))
        else //if E is Exception then
          ShowMessageFmt('Fehler: %s', [Exception(E).Message]);
        //else
        // {nix};
      end);
end;
Ohne Behandlung von FatalException war dein raise etwas umsonst, da es quasi im Nirgendwo verpufft.
Und in Delphi sind (standardmäßig) alle Exceptions vom Typ Exception, so daß es vermutlich eh nicht ausgelöst wird, aber schaden kann der Code auch nichts.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (30. Sep 2014 um 05:00 Uhr)
  Mit Zitat antworten Zitat