0

我在调试时使用一段代码将一行信息写入文件。

    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”只存在于这段代码中。而且,我从来没有以这种方式运行它时出错。

选项或建议?

4

2 回答 2

2

你打电话CloseDispose。您通过语句Close显式和Dispose隐式调用。using两者是等价的,你应该只有其中一个。

这不会引发警告:

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() 方法。

虽然在这种情况下,对象不会抱怨双重处置,但没有真正的理由保留两者,因此在代码风格方面它仍然是一个很好的捕获。

于 2018-10-04T16:04:31.920 回答
1

正如其他人已经提到的那样,这个问题是由于您Close()using块内调用而引起的,并且应该删除该调用。我建议你挖掘并理解为什么这些调用是等价的。

StreamWriter.Close()源代码:

public override void Close() {
   Dispose(true);
   GC.SuppressFinalize(this);
}

以及(base for ) 实现的IDisposable.Dispose()方法如下。这在关闭大括号的块执行时由运行时调用。TextWriterStreamWriterDispose()using

public void Dispose() {
    Dispose(true);
    GC.SuppressFinalize(this);
}

编译器将usingblock 转换为try/finally,因此您的代码等效于:

StreamWriter tw = File.AppendText(fileName)
try {
    tw.WriteLine(line2Write);
    tw.Close();
}
finally {
    tw.Dispose();
}

所以你做了两次同样的事情,因此得到了警告。

仅供参考 - .NET 框架源代码在这里

于 2018-10-04T17:35:59.620 回答