Stream.Disposeは常にStream.Close(およびStream.Flush)を呼び出しています
質問
私は次のような状況がある場合:
StreamWriter MySW = null;
try
{
Stream MyStream = new FileStream("asdf.txt");
MySW = new StreamWriter(MyStream);
MySW.Write("blah");
}
finally
{
if (MySW != null)
{
MySW.Flush();
MySW.Close();
MySW.Dispose();
}
}
私はちょうどMySW.Dispose()
を呼び出し、それが用意されている場合でも、閉じるをスキップすることができますか? (CryptoStreamと同様に)期待通りに動作しない任意のストリームimplimentationsはありますか?
もしそうでなければ、次のようちょうど悪いコードです。
using (StreamWriter MySW = new StreamWriter(MyStream))
{
MySW.Write("Blah");
}
解決
私はちょうどMySW.Dispose(呼び出すことができます)と、 それがあるにもかかわらず、閉じるをスキップ 提供?
はい、それはそれはのためだものです。
任意のストリームの実装があります 予想通り、それは同様に(動作しません。 CryptoStream)?
オブジェクトがIDisposable
を実装している場合、それは適切に自分自身を処分すると仮定しても安全です。
は、そのバグになります。
がない場合は、単に悪い以下れます コード:
いいえ、そのコードがIDisposable
を実装するオブジェクトを扱うの推奨される方法です。
より優れた情報はhref="https://stackoverflow.com/questions/61092/close-and-dispose-which-to-call">閉じると廃棄の
他のヒント
私はリフレクターを使用してSystem.IO.Stream.Dispose
は次のようになりますことを発見します:
public void Dispose()
{
this.Close();
}
は、廃棄して閉じるには、効果的に同じものです。
しかし流れは、それが配置されているとき、()/フラッシュ閉じて呼び出すことはありません。 FileStreamは、(私はキャッシュメカニズムを有する任意の他のストリームを想定)に配置された場合)(フラッシュ呼び出すありません。
あなたはストリーム、またはMemoryStreamをなどを拡張している場合は、あなたは(フラッシュする呼び出しを実装する必要があります)に配置されたときに、それが必要な場合は/閉じます。
StreamWriter.Dispose(両方)とStream.Dispose()オブジェクトが保持しているすべてのリソースを解放します。それらの両方は、基になるストリームを閉じます。
Stream.Dispose()のソースコードは(これは実装の詳細は、それに依存しないことに注意してください):
public void Dispose()
{
this.Close();
}
StreamWriter.Dispose()()(Stream.Disposeと同じ)
protected override void Dispose(bool disposing)
{
try
{
// Not relevant things
}
finally
{
if (this.Closable && (this.stream != null))
{
try
{
if (disposing)
{
this.stream.Close();
}
}
finally
{
// Not relevant things
}
}
}
}
それでも、それらを配置する前に、ストリーム/ streamwriters暗黙的に近い通常I - 私はそれがきれいに見えると思います。
。すべての標準ストリーム(FileStreamを、CryptoStream)が配置された/閉じられたときにフラッシュしようとします。私はあなたがすべてのMicrosoftストリームの実装のためにこれに頼ることができると思います。
フラッシュが失敗した場合は、その結果、クローズ/処分は、例外をスローすることができます。
実際にIIRC、それはフラッシュが例外をスローした場合、ファイルハンドルを解放するために失敗することにあるのFileStreamの.NET 1.0実装のバグがありました。これは添加することにより、.NET 1.1に固定し、最終的に廃棄(boolean)メソッドにブロック/試みます。
手動で閉鎖する必要があるオブジェクトのために、あらゆる努力を使用してブロック内のオブジェクトを作成するために行われるべきである。
//Cannot access 'stream'
using (FileStream stream = File.Open ("c:\\test.bin"))
{
//Do work on 'stream'
} // 'stream' is closed and disposed of even if there is an exception escaping this block
// Cannot access 'stream'
このように1が誤って使用して句の文脈のうち、「ストリーム」をアクセスすることはできませんし、ファイルが常に閉じられます。
私はStreamクラスの.NETソースで見て、それはそうすることができますことを示唆している以下のものを持っていた...
// Stream used to require that all cleanup logic went into Close(),
// which was thought up before we invented IDisposable. However, we
// need to follow the IDisposable pattern so that users can write
// sensible subclasses without needing to inspect all their base
// classes, and without worrying about version brittleness, from a
// base class switching to the Dispose pattern. We're moving
// Stream to the Dispose(bool) pattern - that's where all subclasses
// should put their cleanup starting in V2.
public virtual void Close()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public void Dispose()
{
Close();
}
Stream.Close
はStream.Dispose
するコールまたはその逆によって実現される - ので、方法は等価です。 Stream.Close
は、ストリームを閉じて、ストリームを配置するよりも自然に聞こえるという理由だけで存在してます。
のほかに、あなたは、このメソッドを明示的に呼び出しを回避し、自由のための正しい例外処理を取得するために、代わりにusing
ステートメントを使用しようとする必要があります。