对象可以被多次处理-最佳解决方案

本文关键字:处理 最佳 解决方案 对象 | 更新日期: 2023-09-27 18:04:29

我在以下代码中得到警告CA2202(对象可以被处理多次):

using (Stream responseStream = response.GetResponseStream())
{
    if (responseStream != null)
        using (var br = new BinaryReader(responseStream))
        {
            responseValue = br.ReadBytes(500000);
        }
}

看起来,responseStreams Dispose是在调用BinaryReaders Dispose时调用的。是否BinaryReader总是调用流处理方法?

一种解决方案是直接初始化ResponseStream并让BinaryReader处理流(当然,只有当BinaryReader在任何情况下都要处理流时,这才会起作用)

Stream responseStream = response.GetResponseStream();
if(responseStream != null)
    using (var br = new BinaryReader(responseStream)) //Always disposes the response stream?
        [...]

我可以使用try/finalize而不是外部的using语句来得到这样的结果:

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;
}

当BinaryReader总是释放流时,这看起来不美观,也没有必要。有没有更好的/首选的解决方案来解决这类问题?

对象可以被多次处理-最佳解决方案

您可以实际查看BinaryReader.Dispose是如何实现的:

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);
}

现在的问题是,m_leaveOpen是什么?这是一个标志,表示底层流是否应该被处理!默认设置为false,这意味着底层流将被处理:

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;
    // (...)
}

因此您可以跳过流周围的using语句,因为它无论如何都会被处理:

responseStream = response.GetResponseStream();
if (responseStream != null)
{
    using (var br = new BinaryReader(responseStream))
    {
        responseValue = br.ReadBytes(500000);
    }
}

还是

using (var br = new BinaryReader(response.GetResponseStream()))
{
    responseValue = br.ReadBytes(500000);
}

如果你使用的是VS 2012和。net 4.5,你可以创建一个不会关闭流的BinaryReader。例如:

using(var reader = new BinaryReader(theStream, new UTF8Encoding(), true)
{
//...
}

new UTF8Encoding是默认的,如果你使用BinaryReader(Stream)构造函数,如果你不想要UTF8Encoding,你可以使用其他的东西。true表示"是,保持流打开"。

这样的结构:

public BinaryReader(
Stream   input,
Encoding encoding,
bool     leaveOpen
)

希望这能让你找到你正在寻找的东西。欢呼。