2013-07-21 207 views
0

看到這個代碼更清潔的方式:什麼是處理異常

try 
    { 
     int val = GenericLibrary.ConvertToInt(userInput); 
     return "Valid number"; 
    } 
    catch (Exception) 
    { 
     return "Invalid number"; 
    } 

我寫的是有許多嘗試一個控制檯應用程序, block.I要處理異常的更清潔的方式,並按照DRY原理。

在控制檯應用程序c#中處理錯誤的最佳方式是什麼?

我可以使用Func或Action嗎?

我可以使用面向方面的編程嗎?

+0

不知道這是你的意思,但看看這個:http://stackoverflow.com/questions/3133199/net-global-exception-handler-in-console-application –

+0

@DimitarDimitrov認爲他想刪除所有嘗試抓住和處理集中 –

+0

@ShahroozJefriㇱ那麼,這正是鏈接所指的:) –

回答

0

如果你能想使用Func鍵看到這一點: 您可以使用此

public static class SafeExecutor 
{ 
    public static T Execute<T>(Func<T> operation) 
    { 
     try 
     { 
      return operation(); 
     } 
     catch (Exception ex) 
     { 
      // Log Exception 
     } 
     return default(T); 
    } 
} 

var data = SafeExecutor.Execute<string>(() => 
{ 
    // do something 
    return "result"; 
}); 
+2

請不要編輯問題,使它們適合您的答案,並隱藏OP所具有的關鍵學習困難。謝謝:) –

4

我想澄清,清潔 - 如果你只是想編寫錯誤處理代碼在一個地方,那麼你可以使用AOP(例如PostSharp)。但通過AOP實現錯誤處理程序後,它們將在您的exe文件中隨處編譯。

也請記住,這違反了異常處理程序應該異常使用的規則

我不知道爲什麼你在一個Try-Catch中將string轉換爲int

通過設置全局異常處理程序Application.ThreadExceptionAppDomain.CurrentDomain.UnhandledException,您可以在一個地方處理意外的異常。請記住處理您期望的所有異常,例如將字符串轉換爲int類型。

您可以使用Func進行此演員表,但使用簡單的方法可以更簡單:Integer.TryParse

+1

這是正確的答案:)我鏈接到集中處理異常的答案(只是說,如果有人正在閱讀):) –

3

什麼是清潔取決於很多因素。通過PostSharp或其他AOP處理程序的一般異常處理程序,例如Exception Handling Application企業庫中的塊甚至可以讓您配置您的策略。雖然它是一個好主意,但它在政策注入應用程序塊到位之前從未獲得過多的關注,這也是一個AOP框架,它允許您以可配置的方式集中處理異常。

但實際上異常處理仍然很難。第一條規則應該是永遠不要隱藏異常。你當然可以抓到它們,但是當你不讓它們進一步傳播時,你應該總是記錄它們。如果您的GenericLibrary使用某個配置文件來決定整數應該在哪個區域進行處理,並且沒有找到它的配置文件呢?您會重複出現錯誤,但在調試它之前,您將永遠無法找到根本原因,因爲您會拋棄異常對象並返回字符串。

一個同樣糟糕的「處理」的策略是向

catch(Exception ex) 
{ 
    Log("Error has occured: {0}", ex.Message); 
} 

這會給你錯誤訊息,但你失去了完整的調用堆棧和內部異常。如果您收到一些通用的包裝異常(如僅包含一般錯誤消息的TargetInvocationException),這一點尤其糟糕。

正確的處理策略很大程度上取決於您的具體情況。如果你的意思是控制檯應用程序是一個沒有交付給客戶的小應用程序,那麼通常最簡單的辦法是在第一遍中刪除所有的catch處理程序,並在主要方法中全局處理它們。然後,當你有最常見的非致命錯誤的經驗時,你可以重新添加必要的catch處理程序來恢復穩健性。現在,您繼續致力於解決非致命錯誤,但您仍然堅持致命錯誤策略。

此處的任何以前的答案只會給您使用此策略或策略的建議,但您需要根據具體情況決定哪些例外對您的應用程序無關緊要。當你抓住所有你不知道爲什麼你的應用程序沒有做任何事情,因爲內部錯誤。如果您沒有處理任何應用程序,則會終止每個非致命錯誤(例如,如果值無法在您的應用程序中解析,則可以返回0)。

對於一個小的控制檯應用程序我會

  • 刪除所有catch塊
  • 即使在Main方法

這樣你得到的.NET Framework的自動記錄應用程序事件如果您的應用崩潰,則不需要額外的努力即可登錄如果您的控制檯應用正在執行作爲將輸出打印到控制檯的預定作業不會對您有所幫助。這是處理異常的最乾淨的方式:根本不處理,讓應用程序崩潰,以便您可以找出應用程序事件日誌中出錯的地方。

如果除了您的可執行文件部署pdbs for release版本,您還可以獲得行號和文件信息,這使得在大多數情況下很容易發現錯誤。

如果您的應用程序是關鍵任務或交付給客戶,它可能會發生,你需要使用一些日誌框架登錄到一些私人日誌文件。控制檯應用程序和Windows應用程序之間的區別只是PE標題中的一個標誌。 Windows應用程序將從當前啓動的控制檯分離,而控制檯應用程序將保持與其連接。這是唯一的區別。您也可以在控制檯應用程序中創建一個WPF應用程序,但只要它能運行,它就會阻止您的控制檯,這可能不是您想要的。

但是,如果您切換到Windows應用程序,則可以分配一個新控制檯以使Console.WriteLine發生再次運行,並且您可以繼續使用printf調試,這也許是最常用的調試方法,儘管它是一個相當老舊的調試方法。

通常情況下,您會向您的應用程序添加一個跟蹤庫,以跟蹤您的應用程序流程,該流程默認爲關閉狀態。記錄也應該始終處於開啓狀態,只記錄錯誤。使用這種方法,如果錯誤記錄不夠,您在客戶機器上有更多的麻煩。

+0

+1體育道德。我認爲這個答案適合於OP的水平。你寫道:「當你捕捉到所有你不知道爲什麼你的應用程序因爲內部捕獲錯誤而沒有做什麼的情況時'這不一定是真實的,請看你如何從全局異常處理程序中獲取堆棧跟蹤等, ](http://stackoverflow.com/a/4053325/495455),如果它的內部.net錯誤,你需要winDBG,當你深入挖掘。 –

+0

全局異常處理程序(我的意思是AppDomain.CurrentDomain.UnhandledException)僅在線程啓動方法留下一個異常時才被調用。如果你圍繞主執行和每個執行的線程方法進行捕捉,它將永遠不會被調用。是的,我的措辭不清楚。我的意思是說,如果沒有調試,當你默默地捕捉到所有東西時,爲什麼你的應用程序不正常。 –

+0

不用擔心,謝謝澄清,這是我選擇你的唯一原因:) –

相關問題