Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
322 views
in Technique[技术] by (71.8m points)

.net - To Dispose or not to Dispose (CA2000)

I'm switching on Code Analysis on an older project. Most remarks that result I can understand, but the CA2000: Dispose objects before losing scope is hard to get right.

For instance, this code from an ASP.Net page:

private void BuildTable()
{
    HtmlTableRow tr = new HtmlTableRow();
    HtmlTableCell td = new HtmlTableCell();

    tr.Cells.Add(td);
    // add some controls to 'td'

    theTable.Rows.Insert(0, tr);
    // 'theTable' is an HtmlTable control on the page
}

Gives CA messages:

CA2000 : Microsoft.Reliability : In method 'BuildTable()', call System.IDisposable.Dispose on object 'tr' before all references to it are out of scope.

CA2000 : Microsoft.Reliability : In method 'BuildTable()', object 'td' is not disposed along all exception paths. Call System.IDisposable.Dispose on object 'td' before all references to it are out of scope. (and similar messages about the controls that are added to that 'td'.)

I can resolve the second problem:

private void BuildTable()
{
    HtmlTableRow tr = new HtmlTableRow();
    HtmlTableCell td = new HtmlTableCell();

    try
    {
        tr.Cells.Add(td);
        // add some controls to 'td'

        td = null; // this line is only reached when there were no exceptions
    }
    finally
    {
        // only dispose if there were problems ('exception path')
        if (td != null) td.Dispose();
    }

    theTable.Rows.Insert(0, tr);
}

But I don't think it is possible to resolve the message about the 'tr'. I can't Dispose of that, because it's still needed after the method has exited.

Or did I miss something?

By the way: changing that theTable.Rows.Insert into theTable.Rows.Add changes the CA message to 'not disposed along all exception paths'

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The code analysis is unable to completely understand your code and simply warns if you create a disposable object that seems to not be disposed. In your case you should turn off the warning because the object should not be disposed before leaving the method. You can turn warnings off either for the entire project by customizing the code analysis rule set or on each method having this warning where it is obvious that the code analysis is wrong.

That said, I recommend that you use the using construct when dealing with IDisposable objects:

using (var tr = new HtmlTableRow()) {
  using (var td = new HtmlTableCell()) {
    tr.Cells.Add(td);
    theTable.Rows.Insert(0, tr);
  }
}

Except this code is nonsense as you don't want to dispose the row and cell you just added to the table.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...