C# Streamwriter CA2202:不要多次处理对象
我有一段在调试时用来将一行信息写入文件的代码C# Streamwriter CA2202:不要多次处理对象,c#,streamwriter,idisposable,ca2202,C#,Streamwriter,Idisposable,Ca2202,我有一段在调试时用来将一行信息写入文件的代码 private bool appendLine(string line2Write, string fileName) { try { StreamWriter tw; using (tw = File.AppendText(fileName)) { tw.WriteLine(line2Write);
private bool appendLine(string line2Write, string fileName)
{
try
{
StreamWriter tw;
using (tw = File.AppendText(fileName))
{
tw.WriteLine(line2Write);
tw.Close();
}
}
catch (Exception ex)
{
DialogResult result = MessageBox.Show("Unable to write to: " + fileName + "\r\n" + ex.ToString() + "\r\n OK to retry", "File Sysytem Error", MessageBoxButtons.OKCancel, MessageBoxIcon.Error);
if (result == DialogResult.Cancel)
{
return false;
}
}
return true;
}
我不想让文件保持打开状态,因为如果它是调试信息,我不想在程序崩溃时冒最后一点风险
我可能不明白CA2202告诉我什么
下面是整个错误声明:
警告CA2202对象“tw”可以在方法“familyFinances.appendLine(string,string)”中多次释放。为了避免生成System.ObjectDisposedException,您不应该对对象多次调用Dispose
“tw”仅在此代码中存在。而且,以这种方式运行,我从来没有遇到过错误
选项或建议?您可以调用
关闭和处置。通过使用
语句显式调用Close
,隐式调用Dispose
。这两者是等价的,您应该只拥有其中一个
这不会抛出警告:
private bool appendLine(string line2Write, string fileName)
{
try
{
StreamWriter tw;
using (tw = File.AppendText(fileName))
{
tw.WriteLine(line2Write);
}
}
catch (Exception ex)
{
DialogResult result = MessageBox.Show("Unable to write to: " + fileName + "\r\n" + ex.ToString() + "\r\n OK to retry", "File Sysytem Error", MessageBoxButtons.OKCancel, MessageBoxIcon.Error);
if (result == DialogResult.Cancel)
{
return false;
}
}
return true;
}
规则说明明确说明Close
和Dispose
都是
方法实现包含的代码路径可能导致在同一对象上多次调用System.IDisposable.Dispose或Dispose等效项,例如某些类型上的Close()方法
虽然在这种情况下,对象不会抱怨双重dispose,但没有真正的理由保留这两者,因此在代码样式方面,它仍然是一个很好的捕获。您调用Close
和dispose
。通过使用
语句显式调用Close
,隐式调用Dispose
。这两者是等价的,您应该只拥有其中一个
这不会抛出警告:
private bool appendLine(string line2Write, string fileName)
{
try
{
StreamWriter tw;
using (tw = File.AppendText(fileName))
{
tw.WriteLine(line2Write);
}
}
catch (Exception ex)
{
DialogResult result = MessageBox.Show("Unable to write to: " + fileName + "\r\n" + ex.ToString() + "\r\n OK to retry", "File Sysytem Error", MessageBoxButtons.OKCancel, MessageBoxIcon.Error);
if (result == DialogResult.Cancel)
{
return false;
}
}
return true;
}
规则说明明确说明Close
和Dispose
都是
方法实现包含的代码路径可能导致在同一对象上多次调用System.IDisposable.Dispose或Dispose等效项,例如某些类型上的Close()方法
虽然在这种情况下,对象不会抱怨双重处置,但没有真正的理由保留这两种处置,因此在代码样式方面,它仍然是一个很好的捕获。正如其他人已经提到的,这个问题是由于您使用
块在内部调用而引起的,并且应该删除该调用。我建议你挖掘并理解为什么这些调用是等价的
查看StreamWriter.Close()
源代码:
public override void Close() {
Dispose(true);
GC.SuppressFinalize(this);
}
以及IDisposable.Dispose()
方法,该方法实现如下所示。当使用
块关闭的花括号时,运行时会调用此Dispose()
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
编译器使用
块将转换为try/finally
,因此您的代码相当于:
StreamWriter tw = File.AppendText(fileName)
try {
tw.WriteLine(line2Write);
tw.Close();
}
finally {
tw.Dispose();
}
所以你做了两次同样的事情,因此得到了警告
仅供参考-.NET framework源代码正如其他人已经提到的,此问题是由于您正在使用
块调用内部的而导致的,并且应该删除该调用。我建议你挖掘并理解为什么这些调用是等价的
查看StreamWriter.Close()
源代码:
public override void Close() {
Dispose(true);
GC.SuppressFinalize(this);
}
以及IDisposable.Dispose()
方法,该方法实现如下所示。当使用
块关闭的花括号时,运行时会调用此Dispose()
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
编译器使用
块将转换为try/finally
,因此您的代码相当于:
StreamWriter tw = File.AppendText(fileName)
try {
tw.WriteLine(line2Write);
tw.Close();
}
finally {
tw.Dispose();
}
所以你做了两次同样的事情,因此得到了警告
FYI-.NET framework源代码tw.Close()
是第一个dispose,第二个dispose是离开using
块。tw.Close()
是第一个dispose,而将using
块保留在第二个dispose中。至少对我来说,这是不明显的。而且,它可以解释我一直在使用的其他代码中的问题。谢谢。至少对我来说,这是不明显的。而且,它可以解释我一直在使用的其他代码中的问题。谢谢