Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SPWeb.Site, should you call Dispose() on it?

Updated 06/08/2009 15:52: Short answer NO. Original question:

I can't find any reference which gives guidance on SPWeb.Site regarding disposing. I've gone through some of the more popular best practises documentation on disposing SharePoint objects:

  • http://www.sharepointdevwiki.com/display/public/When+to+Dispose+SharePoint+objects
  • http://msdn.microsoft.com/en-us/library/aa973248.aspx
  • http://blogs.msdn.com/rogerla/archive/2008/02/12/sharepoint-2007-and-wss-3-0-dispose-patterns-by-example.aspx

Unfortunately none of these guidelines mention SPWeb.Site. To give some context, I'm writing a public extension API which accepts an SPWeb as an argument to a method i.e.:

public static void GetWebPartFromCatalog(this SPWeb web, string webPartName)
{
     ......

     SPSite site = web.Site;
     ......

     **OR** ??

     using (SPSite site = web.Site)
     {
         ....
     }
}

I've looked as the Close() method in refelector for SPWeb, which is called by SPWeb.Dispose() and there is nothing in it to indicate the actual SPSite member field is disposed of.

Update: 06/08/2009 13:47

At Alex's suggestion

"Put it in a loop which runs 100 times and use the SPRequestStackTrace registry key described in Troubleshooting SPSite/SPWeb leaks in WSS v3 and MOSS 2007 to check that your test code is the source of the problem."

I ran the following piece of code included inside a webpart:

 for (int i = 0; i < 100; i++)
 {
     using (SPWeb web = SPContext.Current.Site.OpenWeb(""))
     {
            SPSite site = web.Site;
            Debug.WriteLine(site.Url);
     }
 }

Nothing appeared in the SharePoint logs.

Whilst I would hesitate to make any real conclusions from this naive experiment, It would suggest that it's not necessary to dispose of SPWeb.Site. It would be really nice to get a concrete answer from someone more informed on this subject.

Update: 06/08/2009 14:52 Prompted by Greg's Comment I worked out the assignments of m_Site and it appears it's ultimately always passed into SPWeb via the internal constructors. E.g. SPWeb.OpenWeb passes in this to new SPWeb(). So I'm more sure that SPWeb.Site should not be disposed, indeed could cause problems if it was.

like image 881
Edward Wilde Avatar asked Aug 06 '09 09:08

Edward Wilde


2 Answers

Kirk's answer is correct. You must have some handle to an SPSite before an SPWeb can be created, and that is the same SPSite instance you will have when you call SPWeb.Site.

Let's think through the implications of that - if you do not control the creation of the SPSite, but one of its child webs is handed to you from external code, and you dispose the site, when control is returned to the calling code, you've disposed a Site they may not be done with! Put yourself in the calling code's shoes: you pass an SPWeb into a method, and when that method is done, the SPSite you were using has been closed. It is always the instanciator's responsibility to clean up resources they allocate. Do not dispose the SPSite in this case.

like image 157
Rex M Avatar answered Oct 07 '22 02:10

Rex M


Just thinking off the top of my head (dangerous sometimes)...

It seems that you cannot really have a SPWeb without having a SPSite. So, if you got the SPWeb without going through SPSite to get it (either by doing a new SPSite or one being provided to you), then you probably do not need to worry about disposing the SPSite.

This is just conjecture, though. Good question!

like image 31
Kirk Liemohn Avatar answered Oct 07 '22 03:10

Kirk Liemohn