views:

52

answers:

3

If I assign SPContext.Current.Site.OpenWeb().Title to a string, do I need to dispose of it (if possible)?

string title = SPContext.Current.Site.OpenWeb().Title;

I'm still a little fuzzy on when to dispose of sp objects, so I always dispose of my SPWeb and SPSite objects... But, if I don't assign the statement above to an object first, is there any disposing I need to do? I also understand that there are certain cases where using Current eliminates the need to dispose.

Thanks.

+2  A: 

Generally speaking, it doesn't matter whether you save the reference or not - OpenWeb creates a new SPWeb object in memory, and it should be disposed. That is true for all IDisposable objects, not just in SharePoint - it isn't the reference that makes a difference, or the garbage collector could free that memory.

You should change your code to:

string title = null;
using(SPWeb web = SPContext.Current.Site.OpenWeb())
{
    title = web.Title;
}

In theory, had you created a new SPSite you should have disposed of it as well, but not when it comes from SPContext.Current - these objects may be shared with other components.

Kobi
Great, thanks. But, does this mean that any code that uses the variable title, should be inside the using clause?
Josh
@Josh: No, the title is brought over into a managed string and does not have to be disposed of since no managed string type ever needs disposing.
Jesse C. Slicer
Hmmm.... I just read this in Best Practices for disposing of WSS objects: 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.
Josh
Can someone clarify my statement above?
Josh
@Josh - it means you should *not* write `using(SPWeb web = SPContext.Current.Web)` or `SPContext.Current.Web.Dispose()` - I was referring to that in the last sentence.
Kobi
alright, so then if I have something like this: string title = SPContext.Current.Web.Title; - then, I am in the clear.
Josh
@Josh - Yes, its the OpenWeb that is creating the NEW object that needs disposing
Ryan
@kobi: actually in this case, the dispose is redundant. any webs opening using openweb will be automatically disposed of when the owning spsite is disposed. The context site is not owned by you, so it will be disposed by sharepoint at some point in the future, along with all webs opened via openweb. take a look at the openweb code in reflector to verify.
x0n
@x0n - are you sure of that? This is the first I've heard of it, and all guides say you should dispose of these SPWebs, for example, this uncompilable code: http://msdn.microsoft.com/en-us/library/aa973248%28office.12%29.aspx#sharepointobjmodel__spwebobjects (I don't have access to the code you recommend until Sunday, btw)
Kobi
@kobi - I'm certain. Also, don't believe everything you read in those "official" guidelines. There are several mistakes. Some due to incorrect assumptions, and some due to actual bugs in the sharepoint OM. Verify with reflector, and you will be surprised.
x0n
@kobi - for example, the GetPublishingWebs() method guidelines state you should call Close on all of the returned publishing webs to clean up, but this close is ineffectual due to a mistake in the collection constructor - the SPWebs contained within are initialized via the wrong constructor which marks them as owned by the system (and not the caller) so you must call pubWeb.Web.Dispose explicitly to really clean up...
x0n
+2  A: 

In addition to Kobi's answer, please read Best Practices: Using Disposable Windows SharePoint Services Objects from Microsoft. Also, be sure to automatically check your code using Microsoft's SharePoint Dispose Checker Tool.

Jesse C. Slicer
and these guidelines contain several mistakes, so verify with reflector.
x0n
+1  A: 

Actually this is an edge case where the dispose is redundant. It's not going to cause any problems so there's no harm to getting in the habit, so you could leave it there for the moment. It's redundant because any webs opening using openweb will be automatically disposed of when the owning spsite is disposed. The context site is not owned by you, so it will be disposed by sharepoint at some point in the future, along with all webs opened via openweb.

disbelievers: take a look at the openweb code in reflector to verify.

x0n
Wow interesting... makes sense though. I thought you were crazy when I first read this. :)
Kit Menke
@kit - yes, it is interesting, and no, I'm not crazy ;) this behaviour makes the classic inner dispose on a new spsite/openweb using combo also redundant.
x0n