delphi关于try的正确句法结构

流浪 2021-11-26 295

1、句法

 
var LResult:Variant;
//......你在该函数内部需要创建的各类型的实例
try
    try
        //......写与这些创建的各类型的实例相关的代码
    except
        //......进入异常处理:
        on E: ESafecallException do ;        //:比方
        on E: EObjectDisposed do ;            //:比方
        on E: EAccessViolation do ;          //:比方
        on E: EOSError do ;                  //:比方
        on E: EExternalException do ;        //:比方
        on E: EExternal do ;                  //:比方
        else                                  //:比方
        begin
            //......如果有if或case语句:
                //......如果有异常返回值,给它赋值LResult:=....;
                //:彻底释放函数内部创建的引用参照的实例,注意引用参照ARC的类型的释放,具体看该类型的构造函数和解构函数;注意不要误解了“Delphi10.4.2及其后续版本会放弃ARC”的错误提法,其本意是说,原来的处理方式保持不变,$NextGen下一代,新的控件、新的组件、新类型或新的函数,不再在其内部构造ARC的关系啦。若遇TNetHTTPClient的实例的释放,请用MyHTTPClient.DisposeOf;//而不要使用Free;或Destroy;因为你可能将其使用在ARC环境下引用了。
                //:若遇TNetHTTPClient的实例的释放:MyHTTPClient.DisposeOf;
        end;
        //......如果有异常返回值,返回:Result:=LResult;
        exit;//:非常重要,不要试图将其留给fanally子句;事实上,当遇到异常except被中断时,是不会退出fanally的,进程始终保持在fanally的输入阶段并不会让fanally进行任何输出;故而exit之前异常处理一定要释放干净,否则即便用户UI交互后内部仍然会有内存泄漏。
    end;
    //......没有遇到异常的其它代码段:
        //......如果有if或case语句:
            //......如果有返回值,给它赋值LResult:=....;
            //......如果有返回值,返回:Result:=LResult;
finally
    //:彻底释放函数内部创建的各类型的实例;同时注意引用参照ARC的类型的释放,具体看该类型的构造函数和解构函数;注意不要误解了“Delphi10.4.2及其后续版本会放弃ARC”的错误提法,其本意是说,原来的处理方式保持不变,$NextGen下一代,新的控件、新的组件、新类型或新的函数,不再在其内部构造ARC的关系啦。若遇TNetHTTPClient的实例的释放,请用MyHTTPClient.DisposeOf;//而不要使用Free;或Destroy;因为你可能将其使用在ARC环境下引用了。
    //:若遇TNetHTTPClient的实例的释放:if MyHTTPClient<>nil then MyHTTPClient.DisposeOf;

end;

2、运行时刻库基础的except异常类型及中断信号

//System.SysUtils.pas :

{$IFDEF POSIX}
  TEraRange = record
    StartDate : Integer;        // whole days since 12/31/1899 (TDateTime basis)
    EndDate  : Integer;        // whole days since 12/31/1899 (TDateTime basis)
  end deprecated 'Use EraInfo in TFormatSettings';
{$ENDIF}

{ Exceptions }

  PExceptionRecord = System.PExceptionRecord;

  Exception = class(TObject)
  private
    FMessage: string;
    FHelpContext: Integer;
    FInnerException: Exception;
    FStackInfo: Pointer;
    FAcquireInnerException: Boolean;
    class constructor Create;
    class destructor Destroy;
  protected
    procedure SetInnerException;
    procedure SetStackInfo(AStackInfo: Pointer);
    function GetStackTrace: string;
    // This virtual function will be called right before this exception is about to be
    // raised. In the case of an external non-Delphi exception, this is called soon after
    // the object is created since the "raise" condition is already in progress.
    procedure RaisingException(P: PExceptionRecord); virtual;
  public
    constructor Create(const Msg: string);
    constructor CreateFmt(const Msg: string; const Args: array of const);
{$IFNDEF NEXTGEN}
    constructor CreateRes(Ident: NativeUInt); overload;
{$ENDIF !NEXTGEN}
    constructor CreateRes(ResStringRec: PResStringRec); {$IFNDEF NEXTGEN} overload; {$ENDIF !NEXTGEN}
{$IFNDEF NEXTGEN}
    constructor CreateResFmt(Ident: NativeUInt; const Args: array of const); overload;
{$ENDIF !NEXTGEN}
    constructor CreateResFmt(ResStringRec: PResStringRec; const Args: array of const); {$IFNDEF NEXTGEN} overload; {$ENDIF !NEXTGEN}
    constructor CreateHelp(const Msg: string; AHelpContext: Integer);
    constructor CreateFmtHelp(const Msg: string; const Args: array of const;
      AHelpContext: Integer);
{$IFNDEF NEXTGEN}
    constructor CreateResHelp(Ident: NativeUInt; AHelpContext: Integer); overload;
{$ENDIF !NEXTGEN}
    constructor CreateResHelp(ResStringRec: PResStringRec; AHelpContext: Integer); {$IFNDEF NEXTGEN} overload; {$ENDIF !NEXTGEN}
    constructor CreateResFmtHelp(ResStringRec: PResStringRec; const Args: array of const;
      AHelpContext: Integer); {$IFNDEF NEXTGEN} overload; {$ENDIF !NEXTGEN}
{$IFNDEF NEXTGEN}
    constructor CreateResFmtHelp(Ident: NativeUInt; const Args: array of const;
      AHelpContext: Integer); overload;
{$ENDIF !NEXTGEN}
    destructor Destroy; override;
    function GetBaseException: Exception; virtual;
    function ToString: string; override;
    property BaseException: Exception read GetBaseException;
    property HelpContext: Integer read FHelpContext write FHelpContext;
    property InnerException: Exception read FInnerException;
    property Message: string read FMessage write FMessage;
    property StackTrace: string read GetStackTrace;
    property StackInfo: Pointer read FStackInfo;
  class var
    // Hook this function to return an opaque data structure that contains stack information
    // for the given exception information record. This function will be called when the
    // exception is about to be raised or if this is an external exception such as an
    // Access Violation, called soon after the object is created.
    GetExceptionStackInfoProc: function (P: PExceptionRecord): Pointer;
    // This function is called to return a string representation of the above opaque
    // data structure
    GetStackInfoStringProc: function (Info: Pointer): string;
    // This function is called when the destructor is called to clean up any data associated
    // with the given opaque data structure.
    CleanUpStackInfoProc: procedure (Info: Pointer);
    // Use this function to raise an exception instance from within an exception handler and
    // you want to "acquire" the active exception and chain it to the new exception and preserve
    // the context. This will cause the FInnerException field to get set with the exception
    // in currently in play.
    // You should only call this procedure from within an except block where the this new
    // exception is expected to be handled elsewhere.
    class procedure RaiseOuterException(E: Exception); static;
    // Provide another method that does the same thing as RaiseOuterException, but uses the
    // C++ vernacular of "throw"
    class procedure ThrowOuterException(E: Exception); static;
  end;

  EArgumentException = class(Exception);
  EArgumentOutOfRangeException = class(EArgumentException);
  EArgumentNilException = class(EArgumentException);

  EPathTooLongException = class(Exception);
  ENotSupportedException = class(Exception);
  EDirectoryNotFoundException = class(Exception);
  EFileNotFoundException = class(Exception);
  EPathNotFoundException = class(Exception);

  EListError = class(Exception);

  EInvalidOpException = class(Exception);

  ENoConstructException = class(Exception);

  ExceptClass = class of Exception;

  EAbort = class(Exception);

  EHeapException = class(Exception)
{$IFNDEF AUTOREFCOUNT}
  private
    AllowFree: Boolean;
{$ENDIF}
  protected
    procedure RaisingException(P: PExceptionRecord); override;
  public
{$IFNDEF AUTOREFCOUNT}
    procedure FreeInstance; override;
{$ENDIF}
  end;

  EOutOfMemory = class(EHeapException);

  EInOutError = class(Exception)
  public
    ErrorCode: Integer;
  end;

  EExternal = class(Exception)
  public
{$IFDEF MSWINDOWS}
    ExceptionRecord: PExceptionRecord platform;
{$ENDIF}
{$IF defined(LINUX) or defined(MACOS) or defined(ANDROID)}
    ExceptionAddress: LongWord platform;
    AccessAddress: LongWord platform;
    SignalNumber: Integer platform;
{$ENDIF LINUX or MACOS}
  end;

  EExternalException = class(EExternal);

  EIntError = class(EExternal);
  EDivByZero = class(EIntError);
  ERangeError = class(EIntError);
  EIntOverflow = class(EIntError);

  EMathError = class(EExternal);
  EInvalidOp = class(EMathError);
  EZeroDivide = class(EMathError);
  EOverflow = class(EMathError);
  EUnderflow = class(EMathError);

  EInvalidPointer = class(EHeapException);

  EInvalidCast = class(Exception);

  EConvertError = class(Exception);

  EAccessViolation = class(EExternal);
  EPrivilege = class(EExternal);
  EStackOverflow = class(EExternal)
    end deprecated;
  EControlC = class(EExternal);
{$IF defined(LINUX) or defined(MACOS) or defined(ANDROID)}
  EQuit = class(EExternal) end platform;
{$ENDIF}

{$IFDEF POSIX}
  ECodesetConversion = class(Exception) end platform;
{$ENDIF POSIX}

  EVariantError = class(Exception);
  EPropReadOnly = class(Exception);
  EPropWriteOnly = class(Exception);
  EAssertionFailed = class(Exception);
  EAbstractError = class(Exception);
  EIntfCastError = class(Exception);
  EInvalidContainer = class(Exception);
  EInvalidInsert = class(Exception);
  EPackageError = class(Exception);
  ECFError = class(Exception);

  EOSError = class(Exception)
  public
    ErrorCode: DWORD;
  end;

{$IFDEF MSWINDOWS}
  EWin32Error = class(EOSError)
  end deprecated;
{$ENDIF}

  ESafecallException = class(Exception);

  EMonitor = class(Exception);
  EMonitorLockException = class(EMonitor);
  ENoMonitorSupportException = class(EMonitor);

  EProgrammerNotFound = class(Exception);

  ENotImplemented = class(Exception);

  EObjectDisposed = class(Exception);

  EOperationCancelled = class(Exception);

{$IFDEF ANDROID}
  EJNIException = class(Exception)
  public
    ExceptionClassName: string;
    constructor CreateWithClassName(const JNIExceptionClassName: string; const Msg: string);
  end;
{$ENDIF}

{$IF defined(LINUX) or defined(MACOS) or defined(ANDROID)}

{
        Signals

    External exceptions, or signals, are, by default, converted to language
    exceptions by the Delphi RTL.  Under Linux, a Delphi application installs
    signal handlers to trap the raw signals, and convert them.  Delphi libraries
    do not install handlers by default.  So if you are implementing a standalone
    library, such as an Apache DSO, and you want to have signals converted to
    language exceptions that you can catch, you must install signal hooks
    manually, using the interfaces that the Delphi RTL provides.

    For most libraries, installing signal handlers is pretty
    straightforward.  Call HookSignal(RTL_SIGDEFAULT) at initialization time,
    and UnhookSignal(RTL_SIGNALDEFAULT) at shutdown.  This will install handlers
    for a set of signals that the RTL normally hooks for Delphi applications.

    There are some cases where the above initialization will not work properly:
    The proper behaviour for setting up signal handlers is to set
    a signal handler, and then later restore the signal handler to its previous
    state when you clean up.  If you have two libraries lib1 and lib2, and lib1
    installs a signal handler, and then lib2 installs a signal handler, those
    libraries have to uninstall in the proper order if they restore signal
    handlers, or the signal handlers can be left in an inconsistent and
    potentially fatal state.  Not all libraries behave well with respect to
    installing signal handlers.  To hedge against this possibility, and allow
    you to manage signal handlers better in the face of whatever behaviour
    you may find in external libraries, we provide a set of four interfaces to
    allow you to tailor the Delphi signal handler hooking/unhooking in the
    event of an emergency.  These are:
        InquireSignal
        AbandonSignalHandler
        HookSignal
        UnhookSignal

    InquireSignal allows you to look at the state of a signal handler, so
    that you can find out if someone grabbed it out from under you.

    AbandonSignalHandler tells the RTL never to unhook a particular
    signal handler.  This can be used if you find a case where it would
    be unsafe to return to the previous state of signal handling.  For
    example, if the previous signal handler was installed by a library
    which has since been unloaded.

    HookSignal/UnhookSignal setup signal handlers that map certain signals
    into language exceptions.

    See additional notes at InquireSignal, et al, below.
}

const
    RTL_SIGINT          = 0;    // User interrupt (SIGINT)
{$IFDEF MACOS}
    RTL_SIGQUIT        = 1;    // User interrupt (SIGQUIT)
{$ENDIF MACOS}
{$IF Defined(LINUX) or Defined(ANDROID)}
    RTL_SIGFPE          = 1;    // Floating point exception (SIGFPE)
    RTL_SIGSEGV        = 2;    // Segmentation violation (SIGSEGV)
    RTL_SIGILL          = 3;    // Illegal instruction (SIGILL)
    RTL_SIGBUS          = 4;    // Bus error (SIGBUS)
    RTL_SIGQUIT        = 5;    // User interrupt (SIGQUIT)
{$ENDIF LINUX}
    RTL_SIGLAST        = RTL_SIGQUIT; // Used internally.  Don't use this.
    RTL_SIGDEFAULT      = -1;  // Means all of a set of signals that the we capture
                                // normally.  This is currently all of the preceding
                                // signals.  You cannot pass this to InquireSignal.

type
    { TSignalState is the state of a given signal handler, as returned by
      InquireSignal.  See InquireSignal, below.
    }
    TSignalState = (ssNotHooked, ssHooked, ssOverridden);

var

  {
    If DeferUserInterrupts is set, we do not raise either SIGINT or SIGQUIT as
    an exception, instead, we set SIGINTIssued or SIGQUITIssued when the
    signal arrives, and swallow the signal where the OS issued it.  This gives
    GUI applications the chance to defer the actual handling of the signal
    until a time when it is safe to do so.
  }

  DeferUserInterrupts: Boolean;
  SIGINTIssued: Boolean;
  SIGQUITIssued: Boolean;

{$IF Defined(EXTERNALLINKER)}
  DeferSegmentationViolation: Boolean;
  SIGSEGVIssued: Boolean;
  SIGSEGVFaultInstPtr: NativeUInt;
  SIGSEGVFaultAddrPtr: NativeUInt;

procedure CheckAndClearSIGSEGV;
{$ENDIF EXTERNALLINKER}
{$ENDIF LINUX or MACOS or ANDROID}

{$IF Defined(LINUX) or Defined(ANDROID)}
{$IF Defined(LINUX64) and Defined(CPUX64)}
function MapFPE(Context: IntPtr; Code:Integer): TRuntimeError;
{$ELSE}
function MapFPE(Context: IntPtr): TRuntimeError;
{$ENDIF}

{$NODEFINE MapFPE}
function MapFault(Context: IntPtr): TRuntimeError;
{$NODEFINE MapFault}
{$ENDIF LINUX or ANDROID}

https://blog.csdn.net/pulledup/article/details/119296349




DelphiTop论坛申明 1、本网站名称:DelphiTop论坛  网址:www.DelphiTop.com
2、专注于互联网分享精神,专注收藏与分享。你薅网友,我就薅你。
3、本站资源,如发现链接失效,可联系QQ 16643506进行反馈,我们会第一时间更新。
最新回复 (0)
返回