2011-08-22 8 views
15

多くの例外が投げられる可能性がある長いバッチ処理を実行するアプリがあります。バッチ内の1つのアイテムの間に非クリティカル例外がスローされた場合は、単にログに記録して続行して、後で他のバッチアイテムを続行して問題を解決できるようにします。どのような例外を捕まえるべきではないですか?

OutOfMemoryExceptionのようないくつかの例外は、アプリケーション全体に壊滅的なものであり、これらは私がグローバル例外ハンドラにバブルアップしてエラーをログに記録し、アプリケーションを停止するように再提出したいと思います。

私の質問は、(ロギング後に)他のすべてを抑制しながら、私の下の例外ハンドラで再スローすることができる致命的な例外のリストです。

ありがとうございます!

編集:が少し手の込んだ、ここで私のプログラムの基本的な構造は

foreach(var item in longItemList) 
{ 
    try 
    { 
     bigDynamicDispatchMethod(item); 
    } 
    catch(Exception ex) 
    { 
     logException(ex); 
    } 
}

で、このループはトップレベルではかなりあるので、スローされる可能性の例外の膨大な数が潜在的にあります。私のアプリの。プロジェクトのコードの99%がディスパッチ方法の背後にあります。私は低レベルで合理的な例外処理を行いますが、バグはまだ進行しており、例外がスローされた後にバッチ内の他の無関係なプロセスを停止したくありません。

私のアプリの中でどこにでも例外がスローされるのを見つけることは大変な仕事のように思えますし、重大な例外のブラックリストを取得する方が簡単かもしれません。

これに対処するためにアプリを構造化するより良い方法はありますか?私は提案に開放されています。

+0

可能重複http://stackoverflow.com/questions/5507836/which-types- –

答えて

24

「悪い」例外のリストは必要ありません。デフォルトですべてを悪いものとして扱うべきです。あなたが処理して回復できるものだけを捕まえてください。 CLR cannotify未処理の例外があるため、適切にログに記録できます。ブラックリストに載っている例外を除くすべてを呑み込むことは、あなたのバグを修正する適切な方法ではありません。それだけでそれらを覆うだろう。 thisthisを読んでください。例外を転送するため のために引くとき

は、特別な例外を除外しないでください。

catch句に特別な例外のリストを作成する代わりに、 正規に処理できる例外のみをキャッチする必要があります( )。あなたが扱うことができない例外は、非特定例外ハンドラの特殊なケースとして として扱われるべきではありません。 次のコード例は、特別な 例外を再スローするためのテストを誤って示しています。

public class BadExceptionHandlingExample2 { 
    public void DoWork() { 
     // Do some work that might throw exceptions. 
    } 
    public void MethodWithBadHandler() { 
     try { 
      DoWork(); 
     } catch (Exception e) { 
      if (e is StackOverflowException || 
       e is OutOfMemoryException) 
       throw; 
      // Handle the exception and 
      // continue executing. 
     } 
    } 
} 

他のいくつかのルール:アプリケーション コードで、その上、このような などの非特定の例外、のSystem.Exception、System.SystemExceptionをキャッチし、でエラーを処理

は避けてください。アプリケーションでエラーを処理する場合は、 が許容される場合がありますが、このような場合はまれです。

アプリケーションでは、予期しない状態や悪用可能な状態の可能性がある例外を処理しないでください。 すべての可能性のある例外を予測することができず、悪意のあるコードが のアプリケーション状態を悪用できないことを確認した場合は、例外を処理する代わりにアプリケーションを に終了させる必要があります。

なぜ が特定のコンテキストでスローされるのかを理解したら、特定の例外をキャッチすることを検討してください。

回復可能な例外のみをキャッチする必要があります。 の例では、 存在しないファイルを開こうとした結果のFileNotFoundExceptionは、 が問題をユーザーに通知し、ユーザーが別のファイル名 を指定したり、ファイルを作成できるため、アプリケーションが処理できます。 がExecutionEngineExceptionを生成するファイルを開く要求は、 例外の根本的な原因を確実に知ることができず、アプリケーションは が確実に実行されることを保証できません。

Eric Lippert 4つのグループにすべての例外を分類:致命的な、 'Boneheaded'、難問、外因性。使用方法、プログラムエラーやシステム障害:これはMicrosoft's分類とほぼ同じである

Exc. type | What to do       | Example 
------------|-------------------------------------|------------------- 
Fatal  | nothing, let CLR handle it   | OutOfMemoryException 
------------|-------------------------------------|------------------- 
Boneheaded | fix the bug that caused exception | ArgumentNullException 
------------|-------------------------------------|------------------- 
Vexing  | fix the bug that caused exception | FormatException from 
      | (by catching exception because  | Guid constructor 
      | the framework provides no other way | (fixed in .NET 4.0 
      | way of handling). Open MS Connect | by Guid.TryParse) 
      | issue.        | 
------------|-------------------------------------|------------------- 
Exogenous | handle exception programmatically | FileNotFoundException 

:エリックの助言の私の解釈を示します。 FxCopのような静的解析ツールを使用して、これらのルールのsomeを適用することもできます。

+3

厄介な例外も処理できます。ほとんどの状況であなたがそれらを処理しなければならないので、彼らは気にしていません。 –

+0

@エリック:私はあなたの解釈に関する記事を更新しました。 – Dmitry

+2

すごくいいですね! ___ –

11

安全に対処する方法がわからない例外はありません。

キャッチExceptionは特に悪いことですが、唯一悪いのは、管理されている例外タイプを指定していないcatchです(管理されていない例外も同様にキャッチするため)。

+0

.NET 2.0は非CLS準拠の例外(つまり、そのクラスが例外から継承しない例外)を自動的にラップします。 CLS準拠のコードでブロックをキャッチするためにそれらを提示するとき、RuntimeWrappedException;パラメータのないキャッチブロックを使用する理由はまったくありません。 –

+0

私はほとんどの場合、このアドバイスに従いますが、これは特別なケースです。編集を参照してください。 –

1

より適切なデザインは、質問によってサポートされます:Which exceptionsshould私はキャッチしますか?

実際にすべての例外を捕捉しても続行する必要がある場合は、AppDomainと別のワーカープロセスの両方を使用する必要があります。または、ホストをASP.NETまたはタスクスケジューラに変更します。これらのプロセススケジューラは、プロセスの分離と再試行のためのすべての作業を既に完了しています。

+0

ありがとう、これは何かを調べることです。 –

1

HandleProcessCorruptedStateExceptions属性を例外処理関数に適用しない限り、すべての 'ユーザーコードで処理すべきではありません。'例外はすでに無視されていますので、プロセス破損例外を安全に処理できます。

1

次の記事のアドバイスを参照します。

。NET Frameworkの設計ガイドラインのルール:あなたは中のSystem.ExceptionまたはSystem.SystemExceptionをキャッチすることはありません

:あなたは、参照記事からも

http://www.codeproject.com/KB/cs/csmverrorhandling.aspx

を扱うことができない ことの例外をキャッチしませんa キャッチブロック

1

キャッチエラーが発生します。あなたがAPIを使用しているかの方法は、それがスローされますどのような例外を参照してキャッチ史上とき。のみ..あなたは、リストFの例外を作るべきではないと常に

  • は、MSDNのGoogle例外処理から読む...それらをキャッチベストプラクティス
  • はウィットをキャッチすることはありません例外のような非固有の例外
[キャッチしていない、どの例外の種類?]の(
関連する問題