2013-01-20 36 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.