I get the warning CA2202 (Object can be disposed more than once) on the following code:
using (Stream responseStream = response.GetResponseStream())
{
if (responseStream != null)
using (var br = new BinaryReader(responseStream))
{
responseValue = br.ReadBytes(500000);
}
}
It seems like, the responseStreams Dispose is called when the BinaryReaders Dispose is called. Does the BinaryReader always call the Streams Dispose Method?
One solution would be to initialize the ResponseStream directly and let the BinaryReader take care about disposing the stream (which, of course, would only work, if the BinaryReader would dispose the stream in any situation)
Stream responseStream = response.GetResponseStream();
if(responseStream != null)
using (var br = new BinaryReader(responseStream)) //Always disposes the response stream?
[...]
I could use a try/finalize instead of the outer using statement to get something like this:
Stream responseStream = null;
try
{
responseStream = response.GetResponseStream();
if (responseStream != null)
using (var br = new BinaryReader(responseStream))
{
responseValue = br.ReadBytes(500000);
}
}
finally
{
if(stream != null)
stream.Dispose;
}
This isn't nice to look and unnecessary, when the BinaryReader always disposes the stream. Is there a better / preferred solution to solve this kind of problem?
You can actually look how BinaryReader.Dispose
is implemented:
protected virtual void Dispose(bool disposing) {
if (disposing) {
Stream copyOfStream = m_stream;
m_stream = null;
if (copyOfStream != null && !m_leaveOpen)
copyOfStream.Close();
}
m_stream = null;
m_buffer = null;
m_decoder = null;
m_charBytes = null;
m_singleChar = null;
m_charBuffer = null;
}
public void Dispose()
{
Dispose(true);
}
Now, question is, what is m_leaveOpen
? That's a flag which say if underlying stream should be disposed or not! It's by default set to false
, which means underlying stream will be disposed:
public BinaryReader(Stream input) : this(input, new UTF8Encoding(), false) {
}
public BinaryReader(Stream input, Encoding encoding) : this(input, encoding, false) {
}
public BinaryReader(Stream input, Encoding encoding, bool leaveOpen) {
// (...)
m_leaveOpen = leaveOpen;
// (...)
}
So you can skip using
statement around you stream, as it will be disposed anyway:
responseStream = response.GetResponseStream();
if (responseStream != null)
{
using (var br = new BinaryReader(responseStream))
{
responseValue = br.ReadBytes(500000);
}
}
or just
using (var br = new BinaryReader(response.GetResponseStream()))
{
responseValue = br.ReadBytes(500000);
}