Why would I need to call dispose on ASP.NET Controls?

I’m doing some ASP.NET development in VS and have just found an interesting little code suggestion (I think they come from coderush but I could be wrong).

Whenever I’m creating controls it tells me that I should be using a “using” statement for them. I’m a bit confused as to what is going on here though. with the using my code looks something like:

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");
}

So I am expecting that at the end of the using statement it will call dispose on the tableRow. However, the docs in MSDN library says:

The Dispose method leaves the Control
in an unusable state. After calling
this method, you must release all
references to the control so the
memory it was occupying can be
reclaimed by garbage collection.

So I would expect that I now have an unusable object in my control structure so it would break or not render or something. However, everything seems to work just fine.

So what I’m wondering is why are all controls disposable? Is it just because some of them will be and making them all disposable means that one call to dispose at the top level can then be passed down to all child controls recursively?

I think I’d understand if not for the fact that the docs explicitly say that disposing of a control makes it unusable… Are the docs just wrong?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

You shouldn’t actually do this. What you need to do is make sure that listingTable is in the Controls collection so that it will be disposed when the Page is disposed. The listingTable object is then responsible for properly disposing all of its children.

Which is why all Control objects implement the IDisposable interface. That way each parent control can call Dispose on all of its children without first having to test/cast each one. Each control is individually responsible for determining whether it actually has anything that needs to be cleaned up when its Dispose method is called.

The docs are not wrong. Any properly-written object that implements IDisposable and has state data that is actually cleaned up during the dispose process should throw an ObjectDisposedException if any of its public/protected/internal properties or methods are accessed after it has been disposed. (Assume invalid state after Dispose has been called.) Some types will ignore this rule if they don’t actually have anything to clean up, and don’t have to worry about invalid state.

The reason you’re getting a suggestion to wrap it in a using block is because the analyzer doesn’t realize that listingTable will dispose its Rows collection, which will dispose each of the row objects that have been added to it. Also, if an exception is thrown between HtmlTableRow tableRow = new HtmlTableRow() and listingTable.Rows.Add(tableRow), the HtmlTableRow object will be ‘orphaned’ and not be in any other object’s IDisposable hierarchy. Code Analysis wants you to use a try/finally block to immediately dispose of the HtmlTableRow if this happens.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x