簡體   English   中英

Streamwriter CA2202:請勿多次放置對象

[英]Streamwriter CA2202: Do not dispose objects multiple times

我有一段代碼在調試時使用,將一行信息寫入文件。

    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”僅存在於此代碼中。 而且,我從未以這種方式運行過它。

選項或建議?

您稱“ CloseDispose 您可以通過using語句顯式調用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;
}

規則描述明確指出CloseDispose均被考慮

方法實現包含可能導致對System.IDisposable.Dispose或Dispose等效項的多次調用的代碼路徑,例如同一對象上某些類型的Close()方法。

盡管在這種情況下對象不會抱怨雙重處置,但沒有真正的理由要保留兩者,因此就代碼樣式而言,它仍然是一個不錯的選擇。

正如其他人已經提到的,此問題是由於您在using塊內部調用Close()而引起的,因此應刪除該調用。 我建議您挖掘並理解為什么這些調用是等效的。

查看StreamWriter.Close()源代碼:

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

TextWriterStreamWriter基礎)實現的IDisposable.Dispose()方法如下所示。 當關閉using塊的花括號執行時,運行時會調用此Dispose()

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

編譯器using block進行try/finally ,因此您所討論的代碼等效於:

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

因此,您做兩次相同的事情,從而得到警告。

FYI-.NET框架源代碼在這里

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM