2012-09-20 28 views
4

我正在研究一個現有的C#程序,該程序查詢並更改程序以外的各種資源並運行該程序。該程序適用於大多數計算機,但每隔一段時間隨機計算機就會隨機失敗。發生這種情況時,除了用戶告訴我們關於屏幕上拋出的可能或不可能已清除的異常外,爲什麼還沒有反饋。即使他們把它放在屏幕上,它也不會提供給我們有用的信息。自從我修改程序以記錄特定事件並將信息收集到一個文本文件中,我可以用它來近似程序停止的位置。這至少是一個開始,但是通過閱讀stackoverflow.com上的許多主題以及其他論壇,我知道程序需要至少嘗試處理在查詢和修改LDAP,DS,DNS時可能出現的特定異常,SQL等。修改現有程序以更好地處理異常

目前只有很大的try塊圍繞着所有的代碼,每個代碼的最後只有一個catch塊。

private void method_name() 
{ 
    try 
    { 
     //many lines of to do code calling many other methods 
    } 
    catch (exception ex) 
    { 
     MessageBox.Show("An Error has occurred in method_name() :" + ex.Message); 
    } 

我首先想到的是更大的try塊中嵌套更具體的try/catch塊,但我一直運行到與變量成爲在不同環境下無法訪問的問題。例如

try 
{ 
    LdapConnection ldapConn = new LdapConnection(); 
    ldapConn.Connect(details of connection); 
    ldapConn.Bind(details of bind statement); 
    LdapSearchQueue queue = ldapConn.Search(search criteria and such); 
    LdapMessage message; 
} 
catch (somesortofexception ex) 
{ 
    //do something sensible about it 
} 

while ((message = queue.getResponse()) != null) 
{ 
    //do things with message 
} 
ldapConn.Disconnect(); 

問題是消息和隊列在try塊之外無法訪問。這只是我嘗試使用的「//執行調用許多其他方法的代碼的許多行」的一個示例。

因此,這裏是我的問題:

它會更好,試圖使try塊大在上面的例子中,包括while循環和LDAP斷開或剛剛離開大試環路,做一個清單在這期間發生的事情,並在最後創建很多catch塊以捕獲特定的異常?我覺得在特定代碼周圍放入更小的try塊是基於我在本網站上閱讀的內容的方式。

我應該使用像我一直試圖實現的較小的嘗試塊,只需使用一個catch塊,可以捕獲在該小代碼片段中引發的任何異常並將其記錄到我的日誌文件或應該我試着捕捉特定的例外情況?無論如何,除了將它們記錄到文件之外,我並沒有什麼不同之處。

我需要拋出異常嗎?除了純英文的信息說有什麼地方出了問題並聯系IT之外,我並不想讓任何東西冒泡給用戶。目前沒有任何catch塊會拋出任何東西。

+0

這是什麼類型的應用程序?的WinForms?安慰? – McGarnagle

回答

0

關於打破例外,我總是會連接代碼查詢一個分開。

因此,這將成爲:

LdapConnection ldapConn = new LdapConnection(); 
try 
{ 
    ldapConn.Connect(details of connection); 
    ldapConn.Bind(details of bind statement); 
} 
catch (somesortofexception ex) 
{ 
    //Log, send error message.. 
    ldapConn = null; 
} 

if (ldapConn != null) 
{ 
    try 
    { 
     //Do what you need with your connection 
    } 
    catch (Exception ex) 
    { 
     //Log, Error.... 
    } 
    finally 
    { 
     //Disconnect your ldap here 
    } 
} 

理想的情況下,我會把所有的連接代碼和搜索代碼在不同的方法爲好, 所以你有一些更好的堆棧跟蹤。

關於錯誤消息我也只是使用一些通用的消息和日誌異常具體到某種文件(http://logging.apache.org/log4net/)是非常好的,有很好的格式化日誌文件。

+0

如果bind語句出錯,ldapConn.Disconnect()是否也會拋出異常? – GC78

+0

據我所知,如果綁定出現問題,您仍然應該連接,所以斷開應該是安全的調用。調用綁定時,您可以輕鬆地嘗試提供無效憑據。 – catflier

+0

到目前爲止,這一直非常有幫助。只是更多的東西: – GC78

0

只要您預料到該異常,並且可以在本地處理,則吞下特定異常的本地catch塊就沒有問題。在這種情況下,您可以僅基於異常包含的內容向用戶提供信息,或者如果要將日誌和/或消息中的狀態包括在內,則可以將try塊上方的變量定義移動。

對於你並不期待的異常,你應該讓它們向上冒泡到調用堆棧的頂部,在那裏它們可以被全局處理器記錄下來,然後優雅地退出程序。通過吞噬這些例外,你不想通過直立的方式釘住屍體。

假設這是一個WinForms應用程序,全球處理程序的設置看起來是這樣的:

public static void Main(string[] args) 
{ 
    // Switch-off the Windows Forms default handler for unhandled exceptions. 
    // NB From .NET 4 upwards, this won't work if the process state is corrupted. 
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); 

    // Setup event handler to intercept an unhandled exception on a UI thread. 
    // NB The exception will still terminate the application. 
    // But you can show a MessageBox and/or log the exception. 
    Application.ThreadException += 
     new ThreadExceptionEventHandler(App_UiThreadException); 

    // Setup event handler to intercept unhandled exception on a non-UI thread. 
    AppDomain.CurrentDomain.UnhandledException += new 
     UnhandledExceptionEventHandler(App_NonUiThreadException); 

    // Run the application (open main form etc).  
}