为什么我需要在ASP.NET控件上调用dispose?

Chr*_*ris 10 asp.net controls dispose

我正在VS中进行一些ASP.NET开发,并且刚刚发现了一个有趣的小代码建议(我认为它们来自coderush,但我可能错了).

每当我创建控件时,它都会告诉我我应该为它们使用"using"语句.我对这里发生的事情感到有点困惑.使用我的代码看起来像:

using (HtmlTableRow tableRow = new HtmlTableRow())
{
    tableRow.Attributes.Add("class", isOddRow ? "OddRow" : "EvenRow");
    listingTable.Rows.Add(tableRow);
    addCell(tableRow, row, "issueId");
    addCell(tableRow, row, "Title");
    addCell(tableRow, row, "Type");
    addCell(tableRow, row, "Summary");
}
Run Code Online (Sandbox Code Playgroud)

所以我期待在using语句结束时它将在tableRow上调用dispose.但是,MSDN库中的文档说:

Dispose方法使Control处于不可用状态.调用此方法后,必须释放对控件的所有引用,以便可以通过垃圾回收回收它占用的内存.

所以我希望我现在在我的控制结构中有一个不可用的对象,所以它会破坏或不渲染或其他东西.但是,一切似乎都很好.

所以我想知道为什么所有控件都是一次性的?是不是因为它们中的一部分会使它们全部成为一次性意味着可以将一个处于最高级别的处理调用递归传递给所有子控件?

我想如果不是因为文档明确表示处理控件使其无法使用这一事实我会理解......文档是否错误?

Tob*_*oby 14

你不应该真的这样做.您需要做的是确保listingTable在Controls集合中,以便在处置页面时处理它.然后,listingTable对象负责正确处理其所有子代.

这就是所有Control对象实现IDisposable接口的原因.这样,每个父控件都可以调用Dispose所有子控件而无需先测试/转换每个子控件.每个控件都单独负责确定在Dispose调用其方法时是否确实有任何需要清理的内容.

文档没有错.任何正确编写的对象实现IDisposable 并具有在dispose进程中实际清理的状态数据,如果在处置它之后访问其任何public/protected/internal属性或方法,则应抛出ObjectDisposedException.(假设Dispose在调用之后无效状态.)如果某些类型实际上没有任何要清理的东西,则会忽略此规则,并且不必担心无效状态.

你得到一个建议将它包装在一个using块中的原因是因为分析器没有意识到listingTable将处理它的Rows集合,它将处理已添加到它的每个行对象.此外,如果在HtmlTableRow tableRow = new HtmlTableRow()和之间抛出异常listingTable.Rows.Add(tableRow),则HtmlTableRow对象将是"孤立的",而不是在任何其他对象的IDisposable层次结构中.代码分析希望您使用try/finally块立即处理HtmlTableRow如果发生这种情况.