2011-02-15 67 views
2

我在做一些.NET編碼的今天,我遇到了一些我以前沒有想到的 - 許多微軟的內置測試網絡連接(平,TCP套接字等)的方法是約拋出異常非常寬鬆如果連接失敗。可以使用網絡異常來控制流量嗎?

當然,在一般情況下這不是很好用在你的程序的控制流異常。我很好奇,但 - 如果.NET庫,以便隨手扔,我怎樣才能避免這樣的事情(藉口可能是亂碼,只是拼湊爲例):

bool TestConnection(string host) 
{ 
    bool connected; 

    Ping ping = new Ping(); 
    PingReply reply = ping.Send(host); 

    connected = (reply.Status == IPStatus.Success); 

    return connected; // possibly won't return false because of exceptions 
} 

我可以用一個try-catch塊來處理這個異常,但我所做的只是將connected設置爲false。因爲我拋棄了異常的所有信息,是不是基本上吞噬了異常?這裏最好的做法是什麼?

+0

這是*從預期異常*恢復並讓無法處理的情況*冒泡*之間的區別。如果只是一個'布爾'沒有捕獲正常狀態(成功,超時,無路由或任何*想知道*),可能會增加返回的信息。 – 2011-02-15 18:07:46

回答

1

你當然應該趕上由.NET Framework拋出的異常和不承擔你能做的就是返回false,具體取決於應用程序的設計和使用的情況下,你可能會重新拋出異常,並通知上層的唯一的事輸入的網絡路徑不再存在,或者返回false並在其他情況下忽略該問題。

.NET Framework是我們用來構建事物的基礎,並且必須是通用的,如果您嘗試打開一個不存在的文件,它會拋出FileNotFoundException,然後在某些情況下,您創建它並在其他情況下告訴用戶你找不到該文件......它總是取決於你自己的代碼,基本的例外應該通過防禦方法避免或者被捕獲。 :)

0

您應該應該避免使用例外控制流程如果可能。例如,通過使用TryParse而不是Parse,檢查正確的類型或非空值而不是捕獲null參考或類型特例。

但在這種情況下您沒有可用的其他API,因此您必須使用可用的API。請注意,沒有捕捉到例外在你的TestConnection只會意味着你的函數的調用者必須這樣做,這將是更大的邪惡

+1

除非`TestConnection`被命名爲`AssertConnection`。這完全取決於用戶在執行代碼時對你的代碼的期望。你的方法名稱應該符合這些期望。 – 2011-02-15 18:15:34

0

這取決於方法的目的。例如,如果您只想獲得一個布爾值來確定您是否可以建立連接,請捕獲該異常並返回false。

bool CanConnect(string host) 
{ 
    bool connected; 

    Ping ping = new Ping(); 

    try 
    { 
     PingReply reply = ping.Send(host); 
    } 
    catch(/*catch the specific exception(s) here*/) 
    { 
     return false; 
    } 

    connected = (reply.Status == IPStatus.Success); 

    return connected; // possibly won't return false because of exceptions 
} 

但如果你想測試連接,並提供一個更具體的錯誤,爲什麼連接失敗,你不會想趕上這個方法例外。您希望通過允許例外冒出來讓調用者確切地知道發生了什麼問題。

這是微軟對異常處理的指導方針是一致的:

不要過度使用捕捉。通常應允許異常傳播調用堆棧。捕獲您無法合法處理的異常會隱藏關鍵的調試信息。

(來自MS Exception Handling Guidelines

這是不使用異常操作控制流程。 This answer給出了一個使用控制流例外的例子。

0

你在用什麼連接?您應該使用該類的方法,而不是試圖用Ping進行預測試。然後,處理任何連接失敗,因爲它們被拋出。

在一般情況下

它不好用異常在程序的控制流

有時你會捕獲異常,並用它來控制數據流。當架構變更或樣式方法(例如int.TryParse)存在時,您不應該這樣做,並且您肯定應該在任何必須具有高性能的代碼路徑上避免它。

Sometimes you must do evil things。 (是的,這是一個C++ FAQ,但它是一個通用的編程規則)。

此外 - 不要抓住Exception,如果你可以避免它。捕獲特定的派生異常類型。如果你寫一個catch塊,你最好能夠做正確的事情來處理那個位置的異常,或者用throw;(而不是throw new ...)重新拋出。