私は次のコードを持っています
using(MemoryStream ms = new MemoryStream())
{
//code
return 0;
}
dispose()
この方法は、の終了時に呼び出されるusing
文のかっこ}
右?I以来 return
の終了前にusing
声明、うMemoryStream
オブジェクトが適切に配置されても?そこで何が起こるの?
私は次のコードを持っています
using(MemoryStream ms = new MemoryStream())
{
//code
return 0;
}
dispose()
この方法は、の終了時に呼び出されるusing
文のかっこ}
右?I以来 return
の終了前にusing
声明、うMemoryStream
オブジェクトが適切に配置されても?そこで何が起こるの?
回答:
はい、Dispose
呼ばれます。実行が範囲外になるとすぐに呼び出されますusing
ブロックの終了、return
ステートメント、または例外など、ブロックを離れるのにどのような意味があるかに関係なくブロックます。
@Noldorinが正しく指摘しているusing
ように、コードでブロックを使用すると、ブロックで呼び出されてtry
/ finally
にコンパイルされます。たとえば、次のコード:Dispose
finally
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つ。多分両方。
Dispose
inの呼び出しでtry-finallyブロックに効果的にコンパイルされているので、説明したように、の実装が効果的に機能していることがわかりfinally
ます。
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),
SqlCommand comm2 = new SqlCommand("", conn))
{
}
using
声明、オブジェクトにかかわらず、完了パスの処分されます。
参考文献...