当我在下面的代码块上运行代码分析时,我收到以下消息:
对象'stream'可以在方法'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);
}
}
Run Code Online (Sandbox Code Playgroud)
我不明白为什么它可能被调用两次,以及如何修复它以消除错误.有帮助吗?
mxg*_*250 21
我努力解决这个问题,发现这里的例子非常有帮助.我将发布代码以便快速查看:
using (Stream stream = new FileStream("file.txt", FileMode.OpenOrCreate))
{
using (StreamWriter writer = new StreamWriter(stream))
{
// Use the writer object...
}
}
Run Code Online (Sandbox Code Playgroud)
用try/finally替换外部using语句,确保在StreamWriter中使用后将BOTH置为空,并检查以确保在处理之前它在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();
}
Run Code Online (Sandbox Code Playgroud)
这样做可以解决我的错误.
sam*_*amy 13
为了说明,让我们编辑你的代码
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
Run Code Online (Sandbox Code Playgroud)
要避免这种情况,只需直接创建编写器即可
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
Run Code Online (Sandbox Code Playgroud)
edit
:考虑到Eric Lippert所说的话,如果BinaryWriter抛出异常,那么确实只有片段才会被终结器释放.根据BinaryWriter代码,可能在三种情况下发生
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
Run Code Online (Sandbox Code Playgroud)
无论如何,好点,因此编辑:)
明确要求正确实现Dispose,不要关心它是否在同一个对象上被多次调用.虽然对Dispose的多次调用有时表示逻辑问题或代码可以更好地编写,但我改进原始发布代码的唯一方法是说服Microsoft向BinaryReader和BinaryWriter添加一个选项,指示他们不要处理他们的传递 - 在流中(然后使用该选项).否则,即使读者或编写者抛出其构造函数,确保文件被关闭所需的代码也是非常难看的,只是让文件被多次处理似乎更清晰.