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中。至少对我来说,这是不明显的。而且,它可以解释我一直在使用的其他代码中的问题。谢谢。至少对我来说,这是不明显的。而且,它可以解释我一直在使用的其他代码中的问题。谢谢