7

As there was a minor disagreement on whether SPWebs retrieved from SPContext.Current.Site.AllWebs should be disposed, I thought it would be appropriate to post a new question and discuss it here.

I personally think they should be disposed, but I'm interested to hear what other people have to say on this.

If you are planning to respond by linking to Roger Lamb's article, please specify the section that you think is relevant to this question.

3 Answers 3

6

I could be mistaken but I think he's referring to the creation of SPWeb objects when going through the allwebs enumeration.

foreach(SPWeb web in SPContext.Current.Site.AllWebs)
{
    try
    {
    	//do something...
    }
    finally
    {
    	web.dispose();
    }
}

In this case I would dispose of the objects created but not this object: SPContext.Current.Site

3
  • Its a bit unclear: On Roger Lambs blog tinyurl.com/ykjjdq4 Microsoft.SharePoint.SPContext section he mentiones SPContext.Current.Web and say "DO NOT DISPOSE THIS". So why should AllWebs on current site should be any different? On the other hand from the MSDN article tinyurl.com/ygr87rg it is mentioned that SPContext.Current.Site.AllWebs should be disposed and reference the general dispose article -but that article doesnt mention Current.Site.AllWebs ! In general its a bad idea to iterate AllWebs since its a very expensive operation! Jan 10, 2010 at 18:52
  • 2
    AllWebs on current site is different because how does SP know it needs to dispose of all of the items in the enumeration. As you mentioned it's an expensive operation. I doubt the SP code will loop through them all just to check whether they should be disposed or not. Let's take it further, what if you get a list from the SPContext.Current.Web object and then call parentweb on the list. I think you should dispose that parentweb object. Because it is a new SPWeb object. Even though that object represents the same as the SPContext.Current.Web, it's a different object, it should be disposed Jan 10, 2010 at 21:16
  • Correct Steve, I was referring to the SPWeb objects returned by enumering through the AllWebs collection. Jan 11, 2010 at 9:59
3

I think you have to dispose the SPWeb objects when retrieved from the SPSite.AllWebs collection.
If you have look at the implementation of the SPWebCollection class by decompiling it, you can see that everytime a SPWeb is returned, it is instantiated by calling OpenWeb on the SPWebCollection.ISPWebCollectionProvider (which is in this case the SPSite).
Thus, disposing a SPWeb of the SPContext.Current.Site.AllWebs collection will not affect the SPContext.Current.Site instance.

2

You should only dispose objects you create yourself (like new SPSite() or .OpenWeb()).

Read dispose white paper here.

SPContext objects are managed by the SharePoint framework and should not be explicitly disposed in your code. This is true also for the SPSite and SPWeb objects returned by SPContext.Site, SPContext.Current.Site, SPContext.Web, and SPContext.Current.Web.

Since SPDisposeCheck does not find false negatives, you should also read Roger Lamb's "dont dispose guidance" here.

If you want to know more on the internal workings of SharePoint, eg why you need to dispose, then read Hristo Pavlov's excellent article on this subject (be aware that the article exposes reverse enginered code, and that calling some of the public methods he mentions will bring your database in an unsupported state...

2
  • 1
    The white paper explicitly recommends displosing the SPWebs returned from AllWebs. "The SPSite.AllWebs [] index operator returns a new SPWeb instance each time it is accessed. An object is created during the indexing operation even if that object was already accessed. If not properly closed, the following code samples leave an SPWeb object in the .NET Framework garbage collector."
    – Tom Resing
    Oct 14, 2010 at 20:04
  • Noone questions that this is the case. What we are discussing is whether to dispose them if when they come from SPContext.Current. Even when you read the comments of the dispose whitepaper there seems to be confusion. For example Reza states that "You do not need explicitly call Dispose() on any variation of SPContext object and SPSite.RootWeb property. This would interfere with the current context which will be disposed of by SharePoint and results in unexpected behaviors". Oct 15, 2010 at 10:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.