首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >处置或不处置(CA2000)

处置或不处置(CA2000)
EN

Stack Overflow用户
提问于 2010-11-24 09:02:41
回答 5查看 8.9K关注 0票数 13

我正在打开一个旧项目的代码分析。大多数的评论结果我都能理解,但CA2000:在失去作用域之前释放对象是很难得到正确的。

例如,来自ASP.Net页面的代码:

代码语言:javascript
复制
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
}

提供CA消息:

CA2000 : Microsoft.Reliability :在方法'BuildTable()‘中,在对对象'tr’的所有引用超出作用域之前调用System.IDisposable.Dispose。 CA2000 : Microsoft.Reliability :在方法'BuildTable()‘中,对象'td’不是沿所有异常路径释放的。在所有对对象的引用超出作用域之前,在对象'td‘上调用System.IDisposable.Dispose。(以及添加到“td”中的控件的类似消息。)

我可以解决第二个问题:

代码语言:javascript
复制
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);
}

但我认为不可能解决'tr‘的信息。我不能处理它,因为在方法退出之后仍然需要它。

还是我错过了什么?

顺便说一句:将该theTable.Rows.Insert更改为theTable.Rows.Add将CA消息更改为“未沿所有异常路径处理”

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-11-24 09:26:27

代码分析无法完全理解您的代码,只需警告您是否创建了一个似乎未被释放的一次性对象。在您的情况下,您应该关闭警告,因为在离开方法之前不应该释放对象。您可以通过自定义代码分析规则集来关闭整个项目的警告,也可以在每个具有此警告的方法上关闭警告,如果代码分析显然是错误的。

尽管如此,我建议您在处理using对象时使用IDisposable构造:

代码语言:javascript
复制
using (var tr = new HtmlTableRow()) {
  using (var td = new HtmlTableCell()) {
    tr.Cells.Add(td);
    theTable.Rows.Insert(0, tr);
  }
}

(除了这段代码)是胡说八道,因为您不想释放刚才添加到表中的行和单元格。

票数 11
EN

Stack Overflow用户

发布于 2010-11-24 09:56:33

据我所知,您刚才已经表明,CA2000规则在大多数代码基础上并不十分有用,

  • HtmlTableRow上的Dispose没有什么用处,除非它在UI设计器内部使用;我从未见过有人在Asp.net控件上调用dispose。(Winforms/WPF是另一种情况)
  • 您可以将对td的引用存储在表中,因此无论如何都不应该将其释放。

由于上述这两种方法在普通代码中都很常见,我认为CA2000规则对大多数代码库都没有价值--当真正的问题出现时,有如此多的假阳性,您很可能会在50种情况下漏掉1种错误。

票数 3
EN

Stack Overflow用户

发布于 2011-06-04 16:50:37

这段代码将消除两个警告(我使用一个using( HtmlTable )来模拟您的全局HtmlTable成员……):

代码语言:javascript
复制
using (HtmlTable theTable = new HtmlTable())
{
    HtmlTableRow tr = null;
    try
    {
        HtmlTableCell td = null;

        try
        {
            td = new HtmlTableCell();

            // add some controls to 'td'


            tr = new HtmlTableRow();
            tr.Cells.Add(td);

            /* td will now be disposed by tr.Dispose() */
            td = null;
        }
        finally
        {
            if (td != null)
            {
                td.Dispose();
                td = null;
            }
        }

        theTable.Rows.Insert(0, tr);

        /* tr will now be disposed by theTable.Dispose() */
        tr = null;
    }
    finally
    {
        if (tr != null)
        {
            tr.Dispose();
            tr = null;
        }
    }
}

但是,我认为您将考虑使用一种使用子函数的方法来使代码更加清晰:

代码语言:javascript
复制
    private static void createTable()
    {
        using (HtmlTable theTable = new HtmlTable())
        {
            createRows(theTable);
        }
    }

    private static void createRows(HtmlTable theTable)
    {
        HtmlTableRow tr = null;
        try
        {
            tr = new HtmlTableRow();
            createCells(tr);

            theTable.Rows.Insert(0, tr);

            /* tr will now be disposed by theTable.Dispose() */
            tr = null;
        }
        finally
        {
            if (tr != null)
            {
                tr.Dispose();
                tr = null;
            }
        }
    }

    private static void createCells(HtmlTableRow tr)
    {
        HtmlTableCell td = null;

        try
        {
            td = new HtmlTableCell();

            // add some controls to 'td'


            tr.Cells.Add(td);

            /* td will now be disposed by tr.Dispose() */
            td = null;
        }
        finally
        {
            if (td != null)
            {
                td.Dispose();
                td = null;
            }
        }
    }
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4264986

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档