121

私は次のコードを持っています

using(MemoryStream ms = new MemoryStream())
{
     //code
     return 0;
}

dispose()メソッドはusing文中括弧の最後で呼び出されます}よね? ステートメントreturnの終了前なので 、オブジェクトは適切に破棄されますか? そこで何が起こるの?usingMemoryStream

4

5 に答える 5

179

はい、Dispose呼ばれます。実行がブロックのスコープを離れるとすぐに呼び出されusingます。これは、ブロックの実行の終了、returnステートメント、または例外など、ブロックを離れるために必要な手段に関係なく行われます。

@Noldorinが正しく指摘しているように、コードでブロックを使用すると、ブロックで呼び出されて/にusingコンパイルされます。たとえば、次のコード:tryfinallyDisposefinally

using(MemoryStream ms = new MemoryStream())
{
     //code
     return 0;
}

効果的に次のようになります。

MemoryStream ms = new MemoryStream();
try
{
    // code
    return 0;
}
finally
{
    ms.Dispose();
}

したがって、finallyはブロックの実行が終了した後に実行されることが保証されているためtry、その実行パスに関係なくDispose、何があっても呼び出されることが保証されています。

詳細については、この MSDN 記事を参照してください。

補遺:
追加するちょっとした警告:Disposeは呼び出されることが保証されているため、ほとんどのDispose場合、 を実装するときに が例外をスローしないようにすることをお勧めしますIDisposable残念ながら、コア ライブラリには、 が呼び出されたときに特定の状況でスローするクラスがいくつかありDisposeます。WCF サービス リファレンス / クライアント プロキシを見ています。Dispose-- そして、それが発生した場合、元の例外が呼び出しによって生成された新しい例外のために飲み込まれてしまうため、元の例外が例外スタックのアンワインド中に呼び出された場合、元の例外を追跡することは非常に困難になる可能性がありDisposeます。それは非常にイライラすることがあります。それとも、それはイライラするほど怒っていますか?2つのうちの1つ。多分両方。

于 2010-07-14T15:17:19.007 に答える
19

usingステートメントはtry ... finallyブロックとまったく同じように動作するため、常にすべてのコード出口パスで実行されます。finallyただし、ブロックが呼び出されない非常にまれでまれな状況の影響を受けると思います。私が覚えている 1 つの例は、バックグラウンド スレッドがアクティブな間にフォアグラウンド スレッドが終了した場合です。GC 以外のすべてのスレッドが一時停止され、finallyブロックが実行されません。

明らかな編集: IDisposable オブジェクトを処理できるようにするロジックを除けば、それらは同じように動作します。

ボーナスコンテンツ:積み重ねることができます (種類が異なる場合):

using (SqlConnection conn = new SqlConnection("string"))
using (SqlCommand comm = new SqlCommand("", conn))
{

}

また、コンマ区切り (型は同じ):

using (SqlCommand comm = new SqlCommand("", conn), 
       comm2 = new SqlCommand("", conn))
{

}
于 2010-07-14T15:24:40.563 に答える
4

MemoryStream オブジェクトは適切に破棄されるため、心配する必要はありません。

于 2010-07-14T15:17:23.717 に答える
3

このusingステートメントを使用すると、オブジェクトは完了パスに関係なく破棄されます。

参考文献...

于 2010-07-14T15:17:49.307 に答える
0

コンパイルした後、リフレクターでコードを見てください。ストリームで dispose が確実に呼び出されるように、コンパイラがコードをリファクタリングすることがわかります。

于 2010-07-14T15:18:21.220 に答える