0

現在のプロジェクトのコードのさまざまな部分で、

try
{
    //code
}
catch(Exception e)
{
    //display nicely formatted error message
}

私の質問は、コードが既知/想定されるすべてのエラー (オブジェクトが null かどうかのチェックなど) を処理するという前提の下で、アプリケーション グローバル形式でエラーを表示するコードの周りに try-catch を配置する必要があるかどうかです。

それとも、エラーによって例外がスローされ、アプリケーションが自然にクラッシュするようにする方がよいのでしょうか?

ありがとう

4

4 に答える 4

6

このようにすべての例外をキャッチすることは、適切なエラー メッセージを表示するアプリケーションのトップ レベルを除いて、良い方法ではありません。正しく行われれば、プログラムに対するエンド ユーザーの認識は、わずかにバグがあるものの、全体としては合理的であるという認識を維持できます。対照的に、アプリケーションをクラッシュさせることは、エンド ユーザーに、アプリケーションが修復できないほど悪いものであることを納得させる最も簡単な方法です。

例外防止に関する限り、プログラミング エラー (null ポインター、クラス キャスト、範囲外など) と環境エラー (ファイルが見つからない、ネットワーク パスが利用できない、ユーザー入力エラーなど) の 2 種類の例外があります。 ) 第 1 の種類は避けることができますし、第 2 の種類を処理する準備をする必要があります。

于 2012-04-24T02:39:58.527 に答える
3
class PerformTask
{
    public void ConnectToDB(requiredParams)
    {


    }
}

class PerformTaskConsumer
{
   public void SomeMethod()
   {
      try
      {
         PerformTask obj = new PerformTask();
      }

      catch(RelaventExceptions)
      {

      }
   } 


}

可能であれば、例外を避けてください。Exception が発生した場合、その Exception をどう処理するかは呼び出し元に任せます。呼び出し元は、例外に関する適切な形式のメッセージを表示するか、クラッシュするかなどを決定する場合があります。

Eric Lippert には、例外に関する優れた記事があります。ここ

于 2012-04-24T02:37:35.237 に答える
2

ここには2つの異なる考え方があり、両方の支持者はしばしばショックを受け、誰もが他の方法を信じることができることに驚いています。結局のところ、それは好みの問題であり、ターゲットユーザーベースが何を期待および/または受け入れる意思があるか、そしてさらに重要なことに、アプリケーションが何をするかをどれだけよく知っているかです。(あなたの質問は、関係するすべてのコードを記述しなかったことを意味します。そのため、最後のビットはあなたが思っているよりも難しいかもしれません。)

まず、ここでは、クラスライブラリではなく、エンドユーザーアプリケーションについて話していると思います。明示的に処理していないクラスライブラリで例外をキャッチする正当な理由はほとんどありません。あなたは常にその決定を発信者に任せます。

ただし、エンドユーザーアプリケーションでは、コールチェーンの上位に誰もいないため、最終的にはあなたが決定します。この場合、2つの幅広いオプションがあります。

早く失敗する

エラーが発生した場合は、物理的にできるだけ早くアプリケーションをクラッシュさせる方がよいと考える人もいます。少し逆効果に思えますが、未処理の例外が発生することの意味を覚えておいてください。文字通り、何がうまくいかなかったのかわかりません。エラーロギングコードのような単純なものでさえ、予期しない方法で動作する可能性があります。

呼び出しサイトで例外を適切に処理している場合、この種の「予期しない」エラーは、メモリ不足、スタックの破損など、本当に本当に悪いことが起こったときにのみ受け取る必要があります。実際には回復できないようなものです。 、何があっても、試してみても意味がありません。

優雅に失敗する

他の人々は、ユーザーが情報を失うのを防ぐために、可能な限りエラーを分離するように努めるべきだと信じています。アプリケーションが十分にモジュール化されている場合、ある領域での完全な障害が別の領域のデータにまったく影響を与えない可能性があります。

これはよりリスクの高い提案です。一貫性のない状態に陥らないように十分に注意する必要があります。確かに、失敗したコードの何もコードの他の部分から状態を変更していないことを知っている必要があります。

結論は

いつものように、「正しい」答えはおそらく真ん中のどこかにあります。一般に、一貫性のない状態で実行されるリスクは、ほとんどの場合、アプリケーションを停止させる正当な理由です。もちろん、ここでもある程度のロギングを実行することをお勧めします。これは、いくつかの方法で実行できます。私の好みは、これに例外を使用することではなく、thisthis、またはthisのようなトップレベルのさまざまな「未処理の例外」イベントにフックすることです。これらのイベントハンドラーに例外を記録し、「よりわかりやすい」エラーダイアログを表示してから、アプリケーションをシャットダウンします。たとえば、これに似たものを、作成するWPFアプリケーションに配置します。

<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             DispatcherUnhandledException="UnhandledException">


private void UnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
    logger.FatalException("OH NOES! Bad stuff happened, bailing out.", e.Exception);
    MessageBox.Show("holy cow something bad happened:\r\n" + e.Exception.Message);
}

ただし、すべての例外をキャッチしても安全な場合があります。これは主に、何があってもすべてのデータが破棄される場所に限定されます。たとえば、すでに完了した操作の結果を印刷またはエクスポートすると、アプリケーションの他の部分に悪影響を与えることなく、「安全に」失敗する可能性があります。ユーザーがプリンターを持っていないという理由だけでアプリケーションがクラッシュすることはおそらく望ましくありません。(サードパーティの印刷ライブラリが1つあり、明示的System.Exceptionにエラーが発生する場合もあります...)しかし、自分が何をしているのかを理解し、データが他のデータから完全に分離されていることに十分注意する必要があります。システムの。

于 2012-04-24T03:11:29.453 に答える
0

try ... catch ブロックを配置する場所を知るためのヒント。

処理されていないすべての例外をキャッチするために、グローバル例外ハンドラーを配置します。スタック トレースと例外をログに記録し、エンド ユーザーに謝罪を表示して、プログラムを閉じます (ここで続行しないでください)。

アプリケーションがクラッシュしたときにアプリケーションを実行して、理由を確認し、可能な限り最も具体的な例外で例外を正しく処理します。

注意: 例外は例外のためのものであり、通常のプログラムの動作のためのものではありません。

于 2012-04-24T02:48:17.480 に答える