2011-08-26 2 views
6

私はDisposeメソッドを作成しようとしていますが、例外をスローする可能性があります。finallyブロックで例外を検出しました

using(var widget = new Widget()) 
{ 
    widget.DoYourThing(); 
} 

問題は例外がDispose方法によって提起された場合、それが中に提起されている可能性のある例外を置き換えることです:

処分はusing声明を通じて、try-finallyパターンで呼び出されますusingブロックのボディ。通常、この例外は本体にスローされる例外よりもあまり役に立ちません。

Disposeメソッドは、すでに例外が発生している場合には、独自の例外を呑み込むように記述することをお勧めします。以下のようなものが理想的でしょう:

protected virtual void Dispose(bool disposing) 
{ 
    try 
    { 
     this.Shutdown(); 
    } 
    catch(Exception) 
    { 
     this.Abort(); 

     // Rethrow the exception if there is not one already in progress. 
     if(!Runtime.IsHandlingException) 
     { 
      throw; 
     } 
    } 
} 

この情報を提供できるものはありますか?

+5

ここには一般的な問題があります。Disposeパターンを実装する場合、Diposeメソッドはファイナライザスレッドで呼び出すことができます。順番に、ファイナライザのルールはあなたが*投げてはいけないということです。これは、Disposeメソッドが投げてはならないという結論につながる傾向があります。 –

+2

"これは、Disposeメソッドが投げてはならないという結論につながる傾向があります。" - もちろん投げることは避けますが、Dispose実装の中にはスローする必要があるものもあります。たとえば、FileStreamのDisposeメソッドはバッファリングされたデータをフラッシュしようとし、このフラッシュが失敗した場合にスローします。データをフラッシュする際の失敗を黙って無視することは明らかではないので、一般的なケースでは、Disposeメソッドがスローできると考える必要があります。 – Joe

+0

現在、私の 'Dispose'実装は良い実装のような内部メソッドによって発生したすべての例外を取り除きます。例外自体が失われるため、問題が発生します。私は、診断トレースに例外を書いて、実装をそのままの状態に保つ傾向があります。 –

答えて

0
+0

したがって、「Dispose」呼び出しで例外がスローされる可能性がある場合は、 'using'ステートメントで使い捨てオブジェクトを使用しないでください。例外をスローできるメソッドを作成しないでください。多分両方? –

1

は、それが本当に必要なあなたのDisposeメソッドが例外をスローすることができるようにするためですか?

おそらく、別の名前で別の処理メソッドを作成し、必要に応じて例外をスローする必要があります。その後、Disposeを投げないように例外を飲み込むtryブロックでラップされた他のメソッドを呼び出して、Disposeを実装します。

+0

私の例から見ると、 'Shutdown'はあなたが記述する方法とまったく同じです。私の現在の実装は、このメソッドによって生成されたすべての例外を取り除きますが、そのうちのいくつかは貴重です。 –

関連する問題