BinaryReader 在被释放时抛出 NullReferenceException
本文关键字:NullReferenceException 释放 BinaryReader | 更新日期: 2023-09-27 18:31:19
我有一个类MyClass
,它需要来自文件的数据,这些数据将在整个程序运行过程中使用。为了读取数据,我有另一个类OpenFileService
,它派生自IDisposable
并使用BinaryReader
读取所有数据:
internal class OpenFileService : IDisposable
{
#region disposing data
bool disposed = false;
public void Dispose()
{
if (!disposed)
{
Dispose(true);
GC.SuppressFinalize(this);
disposed = true;
}
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
br.Dispose();
}
}
~OpenFileService()
{
Dispose(false);
}
#endregion
internal event EventHandler ErrorInFileReadEventHandler;
internal event EventHandler SuccessfulFileReadEventHandler;
private BinaryReader br;
internal void OpenFile(object obj)
{
MyClass sender = obj as MyClass;
bool isWrongFormat = false;
try
{
br = new BinaryReader(File.Open((sender).fileName, FileMode.Open));
//read in header from file.
if (//header shows wrong file format)
{
isWrongFormat = true;
throw new System.Exception();
}
//read rest of file.
SuccessfulFileReadEventHandler(this,null);
}
catch
{
if (isWrongFormat)
MessageBox.Show("Wrong format.");
else
MessageBox.Show("Couldn't access.");
ErrorInFileReadEventHandler(this, null);
return;
}
finally
{
this.Dispose();
}
}
}
它是这样使用的:
class MyClass
{
internal filePath; //assuming it has already been determined
internal ImageData(string filePath)
{
this.filePath = filePath;
OpenFileService ofs = new OpenFileService();
ofs.ErrorInFileReadEventHandler += new EventHandler(UnsuccessfulFileRead);
ofs.SuccessfulFileReadEventHandler += new EventHandler(SuccessfulFileRead);
Thread thread = new Thread(new ParameterizedThreadStart(ofs.OpenFile));
thread.IsBackground = true;
thread.Start(this);
}
}
现在,当文件格式错误并且我自己在try
块中创建异常时,一切正常没有任何问题,但是当文件实际上无法访问(例如写保护)时,br.Dispose();
创建了一个NullReferenceException
,我无法弄清楚为什么。我真的把代码精简到最基本的东西,我希望它不会太长。
编辑:可能的答案可以从接受的答案中找到 这里作为Microsoft推荐的答案。
如果将
文件打开逻辑拆分为两行,问题可能会变得更加清晰:
try
{
var fs = File.Open((sender).fileName, FileMode.Open);
br = new BinaryReader(fs);
}
finally
{
br.Dispose();
}
当File.Open
调用失败时,将引发异常,而不会为br
字段分配任何内容。当您尝试在finally
块中处置它时,它仍然会null
,因此您的例外。
编辑:我建议解决此问题的方式:
try
{
using (FileStream fs = File.Open(sender.fileName, FileMode.Open))
using (BinaryReader br = new BinaryReader(fs))
{
//read in header from file.
if ( /*header shows wrong file format*/ )
{
isWrongFormat = true;
MessageBox.Show("Wrong format.");
ErrorInFileReadEventHandler(this, null);
}
else
{
//read rest of file.
SuccessfulFileReadEventHandler(this, null);
}
}
}
catch
{
MessageBox.Show("Couldn't access.");
ErrorInFileReadEventHandler(this, null);
}
在此过程中,我已将您的BinaryReader
从字段降级为局部变量。由于您只在 OpenFile
方法中访问它(并在返回之前释放它),因此无需将其引用保留在方法外部。