次のコードチャンクでコード分析を実行すると、次のメッセージが表示されます。
オブジェクト「ストリーム」は、メソッド「upload.Page_Load(object、EventArgs)」で複数回破棄できます。 System.ObjectDisposedExceptionの生成を回避するには、オブジェクトに対してDisposeを複数回呼び出さないでください。
using(var stream = File.Open(newFilename, FileMode.CreateNew))
using(var reader = new BinaryReader(file.InputStream))
using(var writer = new BinaryWriter(stream))
{
var chunk = new byte[ChunkSize];
Int32 count;
while((count = reader.Read(chunk, 0, ChunkSize)) > 0)
{
writer.Write(chunk, 0, count);
}
}
なぜ2回呼び出されるのか、エラーを解消するために修正する方法がわかりません。何か助けはありますか?
私はこの問題に苦労し、例 ここ が非常に役立つことがわかりました。簡単に確認できるようにコードを投稿します。
using (Stream stream = new FileStream("file.txt", FileMode.OpenOrCreate))
{
using (StreamWriter writer = new StreamWriter(stream))
{
// Use the writer object...
}
}
外側のusingステートメントをtry/finalに置き換えて、StreamWriterで使用した後にストリームをnullにすることと、破棄する前にfinallyでnullでないことを確認することの両方を確認してください。
Stream stream = null;
try
{
stream = new FileStream("file.txt", FileMode.OpenOrCreate);
using (StreamWriter writer = new StreamWriter(stream))
{
stream = null;
// Use the writer object...
}
}
finally
{
if(stream != null)
stream.Dispose();
}
これを行うことで私のエラーが解消されました。
説明のために、コードを編集してみましょう
using(var stream = File.Open(newFilename, FileMode.CreateNew))
{
using(var reader = new BinaryReader(file.InputStream))
{
using(var writer = new BinaryWriter(stream))
{
var chunk = new byte[ChunkSize];
Int32 count;
while((count = reader.Read(chunk, 0, ChunkSize)) > 0)
{
writer.Write(chunk, 0, count);
}
} // here we dispose of writer, which disposes of stream
} // here we dispose of reader
} // here we dispose a stream, which was already disposed of by writer
これを回避するには、ライターを直接作成するだけです
using(var reader = new BinaryReader(file.InputStream))
{
using(var writer = new BinaryWriter( File.Open(newFilename, FileMode.CreateNew)))
{
var chunk = new byte[ChunkSize];
Int32 count;
while((count = reader.Read(chunk, 0, ChunkSize)) > 0)
{
writer.Write(chunk, 0, count);
}
} // here we dispose of writer, which disposes of its inner stream
} // here we dispose of reader
edit
:Eric Lippertが言っていることを考慮に入れると、BinaryWriterが例外をスローした場合にのみ、ストリームがファイナライザーによってリリースされる瞬間が実際に存在する可能性があります。 BinaryWriterコードによると、これは3つのケースで発生する可能性があります
If (output Is Nothing) Then
Throw New ArgumentNullException("output")
End If
If (encoding Is Nothing) Then
Throw New ArgumentNullException("encoding")
End If
If Not output.CanWrite Then
Throw New ArgumentException(Environment.GetResourceString("Argument_StreamNotWritable"))
End If
とにかく、良い点、したがって編集:)
BinaryReader/BinaryWriterは、基になるストリームを破棄するときに破棄します。明示的に行う必要はありません。
これを修正するには、ストリーム自体の使用を削除します。
Disposeの適切な実装は、同じオブジェクトで複数回呼び出されても気にしないように明示的に要求されます。 Disposeの複数の呼び出しは、ロジックの問題やより適切に記述できるコードを示している場合がありますが、元の投稿されたコードを改善する唯一の方法は、渡されたコードを破棄しないように指示するオプションをBinaryReaderとBinaryWriterに追加するようにMicrosoftを説得することです。ストリーム内(そしてそのオプションを使用)。そうしないと、リーダーまたはライターがコンストラクターをスローした場合でもファイルを確実に閉じるために必要なコードが十分に醜くなり、ファイルを複数回破棄するだけでクリーンに見えるようになります。
あなたのライターは常にあなたのストリームを破棄します。