Question

The scenario I have, is in the Execute method of a SPJobDefinition I want to go through every SPSite in the web application. So I have the following code:

foreach (SPSite site in this.WebApplication.Sites)
{
  ...
}

Question is, do I need to dispose of each site? The rule I normally go by is dispose or put inside a using only if I new it up myself. Will that Sites property actually contain fully constructed site objects to begin with which I'll only have a reference to in this code. If so then disposing the sites would be dangerous as I'm modifying another object that might want them. Or the opposite is does the Sites property construct the objects on request.. in which case is it my responcibility to dispose of them?

Plus how do I dispose them if I do need to do that. I can't use a using in this case, and will calling a dispose inside the foreach break the enumeration?

Was it helpful?

Solution

Yes you do. See "Writing Applications That Scale to Large Numbers of Users" in Best Practices: Common Coding Issues When Using the SharePoint Object Model. The correct pattern is:

foreach (SPSite site in this.WebApplication.Sites)
{
  try
  {
    ...
  }
  finally
  {
    site.Dispose();
  }
}

Calling dispose will not break the enumeration. It just cleans up the unmanaged memory used by the object.

OTHER TIPS

The guidance here http://www.sharepointdevwiki.com/display/public/When+to+Dispose+SharePoint+objects

suggests that

//loop through each sub site
for (int i = 0; i <= rootweb.Webs.Count; i++)
{
  using (SPWeb subweb = rootweb.Webs[i])
  {
    //do stuff
  }
}

is the prefered solution to this problem.

There is also a tool you can run over your solution to check you are doing things right. http://code.msdn.microsoft.com/SPDisposeCheck

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top