2017-07-03 94 views
0

當我查看.NET Framework中的方法時,它可能會拋出幾個可能的異常。提前規劃異常處理策略

從規劃的角度來看,我需要問什麼來規劃和處理這些例外情況?我明白,取決於異常的影響,這將影響在UI層顯示它。例如,如果後端對用戶體驗不透明的進程拋出異常,那麼您不希望向用戶顯示該進程,因爲他/她不知道該進程是什麼。

感謝

+0

託管VS編譯器把默認的異常處理程序在執行堆棧所以在代碼中的任何未處理的異常得到由默認的處理程序捕獲的頂部,所以把一個例外hanlder在主會捕獲所有異常沒有被代碼中的其他處理程序捕獲,並會停止默認處理程序顯示不需要的異常消息。 – jdweng

回答

0

你通常有一個商業邏輯層在你的應用程序,而且你包裹在安全的調用該庫中的方法。這些方法甚至可以說出他們可以拋出什麼異常,並且如果您願意,您可能希望以獨特的方式處理這些異常。

這裏有幾個類,可以同時處理突發和自定義異常的例子:

class Program 
{ 
    static void Main(string[] args) 
    { 
     MethodInvokationResult result = SafeActionInvokator.HandleSafely(() => 
     { 
      MyFakeBusinessEngine.DivideTwoNumbers(5, 0); 
     }); 
     if (result.Exception is System.DivideByZeroException) 
     { 
      Debug.WriteLine($"A divide by zerp exception was caught"); 
     } 
     else if (!result.Success) 
     { 
      Debug.WriteLine($"An unknown error occured."); 
     } 
    } 
} 

^你可以看到,你可以用呼叫,並在合理的方式處理它們。

public class MethodInvokationResult 
{ 
    public bool Success { get; set; } 
    public Exception Exception { get; set; } 
} 

^一個簡單的結果類

public static class MyFakeBusinessEngine 
{ 
    /// <summary> 
    /// Divides two numbers 
    /// </summary> 
    /// <param name="a">numerator</param> 
    /// <param name="b">denominator</param> 
    /// <returns>the result</returns> 
    /// <exception cref="System.DivideByZeroException">When b is zero, divide by zero exception is thrown.</exception> 
    public static int DivideTwoNumbers(int a, int b) 
    { 
     return a/b; 
    } 
} 

^A有據可查的方法,甚至告訴其他開發人員,預計將拋出什麼異常

public static class SafeActionInvokator 
{ 
    /// <summary> 
    /// Executes a method, and if any exception is thrown, will log the error and swallow the exception. 
    /// </summary> 
    /// <param name="methodToExecute"></param> 
    public static MethodInvokationResult HandleSafely(Action methodToExecute) 
    { 
     try 
     { 
      methodToExecute.Invoke(); 
      return new MethodInvokationResult() 
      { 
       Exception = null, 
       Success = true 
      }; 
     } 
     catch (Exception ex) 
     { 
      Debug.WriteLine($"{ex}"); 
      return new MethodInvokationResult() 
      { 
       Exception = ex, 
       Success = false 
      }; 
     } 
    } 
} 

^該方法的包裝你調用,將其封裝在try catch中允許您以相同的方式處理所有異常,或者將您想要的任何自定義邏輯放在那裏。

這可以擴展爲一個可以返回任何實際結果值的調用。你可以創建一個通用的結果類,而不是我已經展示的簡單結果類。

最後!至於您的實際問題,我會在整個應用程序中創建這些層,並重新引發包含嚴重等級的任何異常。這些會傳播到您的UI層,您可以根據嚴重性選擇要執行的操作。

也許就是這樣!

public class MajorException : Exception { } 
public class MediumException : Exception { } 
public class MinorException : Exception { } 
public class UserError : Exception { } 

希望這有助於!

+0

這是一個非常方便的技術,謝謝!例如,如果應用程序中存在一個關鍵文件(如配置文件),然後應用程序嘗試打開它,那麼這將是一個主要(或致命)異常。在那種情況下,我會關閉應用程序。我期望做的是做一個流程圖,根據它們的性質描述我應該採取的異常行爲。 – dotnetdev

+0

流程圖eh?我強烈推薦yEd Graph Editor - 完全免費,它很棒。我在工作中使用它!只要您可以定義您期望可以處理的異常,就需要人類的大腦力量來認識一行代碼或代碼塊可能出錯,例如您提到的文件訪問。如果你能預料到,你可以處理它。哎呀,你可以預料到總崩潰,只要異常安全處理,你的應用就可以繼續。 –

+0

我應該補充......你可能想要考慮在失敗時應該怎麼做,這可能意味着回滾以前的操作。這可能會讓人毛骨悚然,但有一個你可以使用的UnitOfWork模式,可能利用DotNet框架提供的交易模式......我離題了。 –

0

我想把它寫成一個評論,但它是長註釋文本框...

  1. 但也有例外是重要的,以顯示用戶,因爲他們可以自己處理它,用於例如:文件名是非法的。

  2. 有一些例外,我覺得很重要,因爲他們(用戶)會像我的QA團隊一樣展示用戶,例如:某些方法不會更新GUI,他們可能會得出結論:他們應該進一步報告,他們會告訴我的例外,我會發現我的陣列超出界限...

  3. 也有例外,推動他們的用戶只會混淆他們,像你說的

「他/她本來就是不知道什麼是」

例如,例如:

「如果在不透明的後端進程拋出異常」。

那些我爲自己節省了異常(在數據庫..)..
我總是提醒自己,最終用戶有不同的心理比較開發商( - :

我希望我理解你的問題正確的方式。

+0

是的,你做了感謝,很高興知道你的用戶的觀衆! – dotnetdev