2011-02-15 17 views
2

今日は.NETコーディングを行っていましたが、これまで考えていなかったことがありました。ネットワーク接続(ping、TCPソケットなど)をテストするためのMicrosoftの組み込みメソッドの多くは、例外を投げることについて非常にリベラルです接続が失敗した場合。コントロールフローにネットワーク例外を使用しても問題ありませんか?

もちろん、一般的なケースでは、プログラムの制御フローで例外を使用することは好ましくありません。でも、私は好奇心が強い - .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

*予想される例外からの回復*と処理できない状況を引き起こすことの違い*バブルアップ*。 'bool'だけでは正常な状態(成功、タイムアウト、無ルートなど)を取得できない場合は、返される情報を増やしてください。 –

答えて

1

.NET Frameworkによってスローされた例外を確実にキャッチし、アプリケーション設計と使用例に応じて偽を返すだけであれば、例外を再スローして上位レイヤに通知することはできません入力されたネットワークパスがもう存在しないか、またはfalseを返して、他の場合には問題を無視します。

.NET Frameworkは、物事を構築するために使用する土地であり、汎用でなければなりません。存在しないファイルを開くと、FileNotFoundExceptionがスローされ、場合によっては作成されます。あなたがファイルを見つけることができなかったことをユーザーに伝えます...それは常にあなた自身のコードに依存し、基本的な例外は防御的なアプローチで回避されるか、捕らえられるべきです。 :)

0

を避ける必要があります。の制御フローの例外を使用してください。たとえば、Parseの代わりにTryParseを使用して、nullreferenceまたはtypecaste例外をキャッチするのではなく、正しい型または非ナルをチェックします。

この場合、は利用可能な別のAPIがありませんので、利用可能なものを使用する必要があります。 TestConnection例外をキャッチしないと、の大きな悪いである呼び出し元のが関数を実行しなければならないということになります。

+1

'TestConnection'の名前が' AssertConnection'でない限り。それは、実行時にユーザーがコードにどのような期待を払うかによって決まります。あなたのメソッド名はそれらの期待値と一致する必要があります。 –

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 
} 

しかし、あなたは、接続をテストし、接続が失敗した理由を、より具体的なエラーを提供するために欠けている場合は、この方法で例外をキャッチしたいとは思わないでしょう。あなたは、例外をバブルアップさせることによって、何がうまくいかなかったのかを呼び出し側に正確に知らせる必要があります。

これは、例外処理のためのMicrosoftのガイドラインと一致している:

は使いすぎないキャッチを行います。例外は、呼び出しスタックを伝播することが許可されることがよくあります。 正当に処理できない例外をキャッチすると、重要なデバッグ情報が隠されます。

MS Exception Handling Guidelinesから)

これは、制御フローを操作するために例外を使用していません。 This answerは、制御フローに例外を使用する例を示します。

0

何を接続していますか? Pingで事前テストするのではなく、そのクラスのメソッドを使用する必要があります。その後、スローされたときに接続障害を処理します。

一般的なケースでは、それは時々、あなたが例外をキャッチし、制御フローのためにそれを使用するプログラムの制御フロー

で例外を使用するのはよくないです。アーキテクチャの変更やTryスタイルのメソッド(例:int.TryParse)が存在する場合は実行しないでください。実行する必要のあるコードパスでは避けるべきです。

Sometimes you must do evil things。 (はい、これはC++ FAQですが、一般的なプログラミングルールです)。

また、可能性がある場合は、Exceptionをキャッチしないでください。特定の導出された例外タイプをキャッチします。キャッチブロックを書く場合は、その場所でその例外を処理するために正しいことを行うか、throw;throw new ...ではない)で再スローする方が良いでしょう。

関連する問題