When I run code analysis on the following chunk of code I get this message:
Object 'stream' can be disposed more than once in method 'upload.Page_Load(object, EventArgs)'. To avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object.
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); } }
I don't understand why it might be called twice, and how to fix it to eliminate the error. Any help?
I struggled with this problem and found the example here to be very helpful. I'll post the code for a quick view:
using (Stream stream = new FileStream("file.txt", FileMode.OpenOrCreate)) { using (StreamWriter writer = new StreamWriter(stream)) { // Use the writer object... } }
Replace the outer using statement with a try/finally making sure to BOTH null the stream after using it in StreamWriter AND check to make sure it is not null in the finally before disposing.
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(); }
Doing this cleared up my errors.
To illustrate, let's edit your code
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
To avoid this, just create the writer directly
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
: to take into account what Eric Lippert is saying, there could indeed be a moment when the stream is only released by the finalizer if BinaryWriter throws an exception. According to the BinaryWriter code, that could occur in three cases
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
Anyway, good point, hence the edit :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With