Einzelnen Beitrag anzeigen

Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

AW: Brauche Idee, um immer wiederkehrenden Quellcode zu vermeiden.

  Alt 10. Feb 2015, 08:13
Nein, bitte nicht mit diesem Exception Handling.

Wenn du an etwas Generellem interessiert bist, dann wäre hier etwas
Delphi-Quellcode:
type
  Closure = record
    class function Retry( const AProc: TProc; const MaxRetryCount: Integer = 0 ): TProc; overload; static;
    class function Retry<T>( const AProc: TProc<T>; const MaxRetryCount: Integer = 0 ): TProc<T>; overload; static;
    class function Retry<T1, T2>( const AProc: TProc<T1, T2>; const MaxRetryCount: Integer = 0 ): TProc<T1, T2>; overload; static;
    class function Retry<T1, T2, T3>( const AProc: TProc<T1, T2, T3>; const MaxRetryCount: Integer = 0 ): TProc<T1, T2, T3>; overload; static;
  end;

 { Closure }

class function Closure.Retry( const AProc: TProc; const MaxRetryCount: Integer ): TProc;
begin
  Result := procedure
    var
      LRetryCount: Integer;
    begin
      LRetryCount := 0;
      while True do
        try
          AProc( );
          Exit;
        except
          Inc( LRetryCount );
          if LRetryCount >= MaxRetryCount
          then
            raise;
        end;
    end;
end;

class function Closure.Retry<T1, T2, T3>( const AProc: TProc<T1, T2, T3>; const MaxRetryCount: Integer ): TProc<T1, T2, T3>;
begin
  Result := procedure( Arg1: T1; Arg2: T2; Arg3: T3 )
    begin
      Retry(
        procedure
        begin
          AProc( Arg1, Arg2, Arg3 );
        end, MaxRetryCount )( );
    end;
end;

class function Closure.Retry<T1, T2>( const AProc: TProc<T1, T2>; const MaxRetryCount: Integer ): TProc<T1, T2>;
begin
  Result := procedure( Arg1: T1; Arg2: T2 )
    begin
      Retry(
        procedure
        begin
          AProc( Arg1, Arg2 );
        end, MaxRetryCount )( );
    end;
end;

class function Closure.Retry<T>( const AProc: TProc<T>; const MaxRetryCount: Integer ): TProc<T>;
begin
  Result := procedure( Arg: T )
    begin
      Retry(
        procedure
        begin
          AProc( Arg );
        end, MaxRetryCount )( );
    end;
end;
Im Übrigen sollten die Aufrufe FDB.TuDies und FDB.TuDas sich selber um den Lock (wieso eigentlich Mutex, brauchst du das Session- bzw. System-Global? Sonst würde ein TMonitor reichen) kümmern, denn der scheint ja immanent wichtig zu sein, also gehört der in diese Methoden rein.
Delphi-Quellcode:
type
  TFoo = class
  public
    procedure Foo( AParam: Integer );
    procedure Bar( AParam1, AParam2: Integer );
  end;

  { TFoo }

procedure TFoo.Bar( AParam1, AParam2: Integer );
begin
  TMonitor.EnterAutoLeave( Self ); {Lock}

  Writeln( 'TFoo.Bar(', AParam1, ',', AParam2, ')' );
end;

procedure TFoo.Foo( AParam: Integer );
begin
  TMonitor.EnterAutoLeave( Self ); {Lock}

  Writeln( 'TFoo.Foo(', AParam, ')' );
end;
Dieses TMonitor.EnterAutoLeave kommt durch einen class helper von mir, der ein Interface zurückliefet und dafür für das automatische Verlassen sorgt. Dadurch wirkt der Code gleich viel entspannter.

Aufruf von der gesamten Hütte ist jetzt ein gemütlicher Spaziergang
Delphi-Quellcode:
procedure Test;
var
  LFoo: TFoo;
begin
  LFoo := TFoo.Create;
  try
    Closure.Retry<Integer>( LFoo.Foo, 10 )( 42 );
    Closure.Retry<Integer, Integer>( LFoo.Bar, 10 )( 08, 15 );
  finally
    LFoo.Free;
  end;
end;
Lustig gell?

UPDATE

Ok, das mit dem Mutex habe ich jetzt auch verstanden, damit garantierst du, dass nur einer global auf die Datenbank zugreift. Ansonsten schmeisst der Mutex eine Exception. Das ändert aber nichts an meinem Vorschlag, ausser, dass man den Closure noch erweitert um ein Predicate, dass den Exception-Typ bekommt und dort entschieden wird, ob da wirklich weitergemacht werden soll, denn eine EAccessViolation ist nichts, wo ich es nochmals versuchen müsste, da ich ja eigentlich auf nur auf den Mutex warte.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (10. Feb 2015 um 08:27 Uhr)
  Mit Zitat antworten Zitat