2013-01-20 37 views
4

有些东西我一直在运行,我真的没有用Delphi程序解决,并想知道是否有人可以指示我。正如话题所说,你如何做适当的灾难性错误处理?例如:适当的灾难性错误处理

// is file necessary for the program present? 
if not FileExists(FilePath1) then 
    begin 
    raise Exception.Create(FilePath1 + ' does not exist and is required for this program to function.'); 
    // I obviously need to do something here to make the program QUIT and not have 
    // any more code run. 

    Application.Terminate; 
    Abort; 
    end; 

我可以在那里使用异常单元,并抛出一个异常,但程序继续像以前一样。我过去曾经使用过停止呼叫,但它似乎没有做任何清理或类似的事情,所以我最终做出了一个大的程序,通过密切和免费的电话为我所做的一切事情做好了准备(甚至我我不确定任何幕后的东西)。

那么处理这些事情的正确方法是什么?

编辑:为了澄清,我想知道如何让程序做它需要做的清理工作,然后立即退出并且不做任何其他代码。

+0

你需要一些条件之后,干净的退出?怎么样调用Application.Terminate? – jachguate

+0

@jachguate是的,我想要一个干净的出口。但是这种调用仍然会导致在显示表单不合逻辑的情况下显示表单。 – Glenn1234

+0

你的问题在哪里,你说你不希望任何表单被显示? – jachguate

回答

1

您可以通过调用Application.Terminate来指示应用程序全局对象终止程序。

调用终止以编程方式结束应用程序。通过调用Terminate而不是释放应用程序对象,允许应用程序以有序的方式关闭

终止调用Windows API PostQuitMessage函数到执行应用程序的有序关闭。终止不是直接的。

由于可能会出现调用堆栈中的更深,你也可以raise an Exception,和你的代码程序,以便让执行到达主应用程序循环和默认的异常处理程序捕捉它不处理它。

这样,您可以有效防止更多的代码在您的应用程序中运行。

在代码中它可能看起来像这样:

if not FileExists(FilePath1) then 
    begin 
    MessageDlg(FilePath1 + ' does not exist and is required for this program to function.', 
       mtWarning, [mbOK], 0); 

    Application.Terminate; 
    Abort; //raising a EAbort just as an example 
    end; 

根据其中的代码被调用时,我劝你还是不要直接显示信息,而是提高与消息的异常,让应用程序对象默认的HandleException方法为你显示消息:

if not FileExists(FilePath1) then 
    begin 
    Application.Terminate; 
    raise EMyFatalException.Create(FilePath1 
     + ' does not exist and is required for this program to function.'); 
    end; 

对我来说看起来更自然。 EMyFatalException是一个假设的异常类,您可以声明并且永远不会在您的except子句中处理。

+0

第二个代码块快速闪烁一个盒子,然后终止。我有德尔福3在这里我正在测试它(现在对我来说很方便),如果这是有用的知道。 – Glenn1234

+0

第一个呢? – jachguate

+0

显示消息,然后闪烁主窗体并终止 - 基本上我现在可以做的最好的。 – Glenn1234

2

恕我直言,唯一干净的方式是在应用程序运行之前检查“致命条件”。

program Project2; 

uses 
    Forms,Dialogs, 
    Unit1 in 'Unit1.pas' {Form1}; 

{$R *.res} 

begin 
    ReportMemoryLeaksOnShutDown := true; 
    Application.Initialize; 
    if True then // your condition here 
    begin 
     MessageDLG('Fatal Error',mtError,[mbok],0); 
    end 
    else 
    begin 
     Application.CreateForm(TForm1, Form1); 
     Application.Run; 
    end; 
end. 

任何其他方法将有副作用

unit Unit1; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs; 

type 
    TForm1 = class(TForm) 
    procedure FormCreate(Sender: TObject); 
    private 
    { Private-Deklarationen } 
    FSL:TStringList; 
    public 
    Destructor Destroy;override; 
    { Public-Deklarationen } 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

destructor TForm1.Destroy; 
begin 
    FreeAndNil(FSL); 
    Showmessage('Will never be seen with Application.Terminate + HALT'); 
    inherited; 
end; 

procedure TForm1.FormCreate(Sender: TObject); 
const 
    Testing=0; // try 1 and 2 too 
begin 

    FSL:=TStringList.Create; 
    Try 
     raise Exception.Create('Terminating now'); 
    except 
    case Testing of 
     0: begin 
      // exception object will not be freed other code will be prevented, Form won't be shown 
      Application.Terminate; 
      HALT; 
      end; 
     1: begin 
      // exception object will not be freed Form won't be shown 
      HALT; 
      end; 
     2: begin 
      // clean but Form will be shown 
      Application.Terminate; 
      end; 

    end; 
    end; 

end; 

end. 
+0

我尝试建议的第一种方法,但OP似乎担心修改* .dpr文件。 – TLama

+0

@TLama你删除了你的帖子?也许你应该取消删除它,如果你取消删除了你的内容,我会删除它。在我看来,如果可以避免硬性放弃,那就应该完成。 – bummi

+0

让我们保持它原样。你的答案比我的范围更广。 – TLama

6

要执行异常终止呼叫暂停()传递的退出代码。

if CatastropicErrorDetected then 
begin 
    ... show error message 
    Halt(1); 
end; 

在Windows上,导致调用TerminateProcess并将那里,然后停止执行。

你注意到没有执行清理,通常这就是你想要的。由于您在应用程序启动时执行此检查,因此应该没有任何清理操作。

1

您可以编写自己的Application.OnException处理程序,例如:

unit Unit1; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, StdCtrls; 

type 
    TForm1 = class(TForm) 
    Button1: TButton; 
    procedure Button1Click(Sender: TObject); 
    private 
    procedure HandleException(Sender: TObject; E: Exception); 
    end; 

var 
    Form1: TForm1; 

type 
    EMyFatalError = class(Exception); 

implementation 

{$R *.dfm} 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    Application.OnException:= HandleException; 
    raise EMyFatalError.Create('OOPS!'); 
end; 

procedure TForm1.HandleException(Sender: TObject; E: Exception); 
begin 
    Application.ShowException(E); 
    if E is EMyFatalError then 
    Application.Terminate; 
end; 

end.