C# 对象可以多次处置-最佳解决方案
我在以下代码中得到警告CA2202(对象可以被多次处置):C# 对象可以多次处置-最佳解决方案,c#,dispose,C#,Dispose,我在以下代码中得到警告CA2202(对象可以被多次处置): using (Stream responseStream = response.GetResponseStream()) { if (responseStream != null) using (var br = new BinaryReader(responseStream)) { responseValue = br.ReadBytes(500000);
using (Stream responseStream = response.GetResponseStream())
{
if (responseStream != null)
using (var br = new BinaryReader(responseStream))
{
responseValue = br.ReadBytes(500000);
}
}
似乎在调用BinaryReaders Dispose时调用了responseStreams Dispose。BinaryReader是否总是调用Streams Dispose方法
一种解决方案是直接初始化ResponseStream,并让BinaryReader处理流(当然,只有在任何情况下BinaryReader处理流时,这才有效)
我可以使用try/finalize而不是outer 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总是处理流时,这看起来不好,也没有必要。是否有更好的/首选的解决方案来解决此类问题 如果将VS 2012与.NET 4.5一起使用,则可以创建不会关闭流的BinaryReader。例如:
using(var reader = new BinaryReader(theStream, new UTF8Encoding(), true)
{
//...
}
如果使用BinaryReader(Stream)构造函数,则默认使用新的UTF8Encoding,如果不需要UTF8Encoding,则可以使用其他方法。true表示“是的,让溪流保持开放”
结构如下:
public BinaryReader(
Stream input,
Encoding encoding,
bool leaveOpen
)
希望这能引导你找到你想要的东西。
干杯。您实际上可以看看它是如何实现的:
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;
// (...)
}
因此,您可以使用流周围的语句跳过,因为它将被处理:
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);
}
Gaurav给出了下面的答案,但我只是想指出,“如果一个对象的Dispose方法被多次调用,那么该对象必须忽略第一次调用之后的所有调用。-这意味着这应该不是问题(除了您可能在一个地方处置了它,然后以后继续尝试使用它,这是另一个问题)。我正在处理的项目基于.NET 4,因此leaveOpen选项不可用。但感谢您的提示!感谢您对.NET Framework参考源的详细解释和提示,我不知道:)
using (var br = new BinaryReader(response.GetResponseStream()))
{
responseValue = br.ReadBytes(500000);
}