2009-08-05 77 views
2

這是一個問題,我的現實世界編程經驗不足閃耀。我有一個功能,這使得調用其他三個功能:我該如何優雅地退出我的應用程序出錯?

Public Sub StartService() 
    RunSearch() 
    SaveMessages() 
    DeleteMessages() 
End Sub 

內的每個我在用的嘗試Catch語句來捕獲錯誤的方法RunSearch(), SaveMessages() and DeleteMessages()。現在,我發現錯誤並寫入錯誤日誌時,出現RunSearch()錯誤,但是我也從SaveMessages()DeleteMessages()得到兩個錯誤,因爲這些函數依賴於RunSearch()不返回錯誤。我正試圖建立良好的錯誤捕捉基礎,所以我不只是想在出現錯誤時殺死應用程序。我的問題是:如果RunSearch()中發生錯誤,我該如何優雅地停止執行。

回答

5

爲什麼RunSearch不記錄問題後重新拋出異常?

如果你不想撥打SaveMessages()如果RunSearch()失敗,那麼不要這樣編碼。

我的一般想法是每個方法的接口都指定一個「協議」。它必須在出現問題時表明其行爲。方法包括:

  1. 如果我得到一個錯誤,我將終止該過程。這非常極端,限制了您的方法的可重用性。
  2. 我會返回一個計數或狀態代碼或somesuch。由您決定是否檢查以及是否有任何特定的狀態碼意味着調用其他方法是安全的。我寧願不依賴客戶記住檢查狀態代碼。
  3. 如果我失敗了,我會留下一些東西,以便後續的處理過程能夠保持健全。例如,如果我的工作是創建鏈表,那麼在發生錯誤時,我不會留下懸掛的指針或初始化列表。你可能會得到一個空的列表,但至少格式良好的後續處理將起作用。這往往意味着與其他方法達成某種程度的一致性(即耦合)。這通常是最好的方法,尤其是在配合良好的問題記錄的情況下。
  4. 如果我不能完成這項工作,我會拋出異常。如果你再次調用它,這個異常會指出是否有一些事情可以工作(我使用TransientException和InvalidRequestException相當多)。異常是有用的,因爲客戶端不能(對於Java檢查異常)意外忽略它們。在處理諸如「無法打開數據庫」等問題時,這似乎是合理的。我們真的不希望人們誤以爲「這個人沒有犯罪記錄」甚至不能進入數據庫。「
+0

另一個很好的建議。豎起大拇指,併爲你和@Rob Thijssen upvote。 – David 2009-08-05 13:43:27

+0

啊。這個答案是關於設計的。編寫代碼是很有吸引力的,但它確實有助於首先考慮一些事情(並記錄答案)。 – Bill 2009-08-05 14:07:15

3

一個可能的選擇是將RunSearch方法更改爲返回Boolean - 如果成功則返回True,如果發生阻塞其他兩個函數的錯誤,則返回False。

然後,你可以這樣做:

Public Sub StartService() 
    If RunSearch() Then 
     SaveMessages() 
     DeleteMessages() 
    End If 
End Sub 
1

在完成日誌記錄之後,您可以重新拋出方法異常,然後將您的RunSearch()方法包裝在try/catch塊中,以便接下來的兩個方法不會運行。

1

看起來好像你可能不需要底層的方法級錯誤處理程序,而只是高級/應用程序級的處理程序。如果每個方法的所有catch塊都是相同的,我建議切換到高級錯誤處理程序。作爲一般規則,您只需要捕獲您可以明確處理的異常,或者爲了記錄目的在最後一次運行時捕獲異常,並防止不整潔的應用程序崩潰。

這是我會怎麼處理它

public void StartService() 
{ 
    try 
    { 
     RunSearch(); 
     SaveMessages(); 
     DeleteMessages(); 
    } 
    catch(Exception ex) 
    { 
     //Do Nothing or Log ex 
    } 
} 

public void RunSearch() 
{ 
//No error handler here, as this method cannot recover from exceptions 

//RunSearch functionality 
} 
+0

如果你縮進你的代碼4個空格,我們得到的語法突出顯示... – grenade 2009-08-05 14:14:53

+0

沒有冒犯馬特,但如果問題是在VB從一個被承認的初學者,我建議在VB中回答。 – Bill 2009-08-05 14:31:36

+0

@Rob。謝謝,忘了格式化 @Bill。理解點,但OP標記了C#這個問題,所以假設它是可以的 – MattH 2009-08-05 14:40:57

0

你不應該使用異常來控制程序流程。改用返回值。投擲和捕捉異常代價昂貴,只能用於報告代碼中真正意想不到的情況。

大衛斯特拉頓的上面的答案是一個更好的解決方案。

相關問題