SPSite and SPWeb implement the IDisposable interface
General Guidelines1. Using a disposed object can cause more problems than failing to dispose.There are some situations where it is not clear if an object is safe to Dispose or not. When in doubt, err on the side of caution and let SharePoint clean up after itself. All SPWeb objects will be disposed as part of their parent SPSite's disposal process. Similarly, all SPSite objects are disposed when the thread ends. A potential memory leak is probably preferred to receiving an exception: "Trying to use an SPWeb object that has been closed or disposed and is no longer valid." 2. An object should be disposed as soon as it is no longer needed.An object can be safely disposed after the last access to a child object of that object. A child object is any object (or child of an object) that stores a reference to the object from which it is created. For example, an SPListItem is a child of an SPWeb, which is a child of an SPSite. 3. Objects should be disposed in the same method where they are allocated.The easiest mechanism for ensuring proper disposal is the using statement (C# A common anti-pattern looks something like this: SPList GetList(string webUrl, string listName)
{
SPSite site = new SPSite(webUrl);
SPWeb web = site.OpenWeb();
return web.Lists[listName];
}
void DoSomething(string webUrl, string listName)
{
SPList list = GetList(webUrl, listName);
// Do something with list
list.ParentWeb.Site.Dispose();
}
With the object instantiation and disposal separated, it is much more likely that something will get disposed too early or not at all. A better approach might look like this: void DoSomethingHelper(SPWeb web, string listName)
{
SPList list = web.Lists[listName];
// Do something with list
}
void DoSomething(string webUrl, string listName)
{
using(SPSite site = new SPSite(webUrl)
{
using(SPWeb web = site.OpenWeb())
{
DoSomethingHelper(web, listName);
}
}
}
4. Be extremely careful with iterating through collections.There are some circumstances where it is necessary to iterate through collections of SPWeb or SPSite objects.
//loop through each sub site foreach (SPWeb subweb in rootweb.Webs) { //do stuff } In the example above this would not be disposing of each subweb correctly. The below sample shows how this can be handled correctly. //loop through each sub site for (int i = 0; i <= rootweb.Webs.Count; i++) { using (SPWeb subweb = rootweb.Webs[i]) { //do stuff } } To safely use these collections with LINQ, consider using an iterator: Source public static IEnumerable<SPWeb> AsSafeEnumerable(this SPWebCollection webs) { foreach (SPWeb web in webs) { try { yield return web; } finally { web.Dispose(); } } } Usage: var lists = from w in site.AllWebs.AsSafeEnumerable() from SPList l in w.Lists where !l.Hidden && !w.IsRootWeb select new { WebTitle = w.Title, ListTitle = l.Title }; 5. Only dispose objects owned by the developer's code.Keeping Guideline 1 in mind, here are the common sources of SPSite and SPWeb objects that may or may not be the developer's responsibility to Dispose. Objects owned by the developer:SPSite Constructor
|
| This guidance does not apply to the PersonalSite |
Miscellaneous
Objects owned by SharePoint:
SPSite.RootWeb
This property returns a shared SPWeb instance and is used internally in several methods and properties. It should never be disposed explicitly. Source![]()
SPSite site = SPContext.Current.Site; SPWeb rootWeb = site.RootWeb; // Process rootWeb // NO rootWeb.Dispose()
SPContext
- SPContext.Web (and SPContext.Current.Web)
- SPContext.Site (and SPContext.Current.Site)
Feature Receiver
SPFeatureReceiverProperties.Feature.Parent for a Site- or Web-scoped feature receiver should not be disposed.
public override void FeatureActivated(SPFeatureReceiverProperties properties) { SPWeb web = properties.Feature.Parent as SPWeb; // Process web // NO web.Dispose() }
Event Receiver
- SPWebEventProperties.Web
- SPListEventProperties.Web
- SPListEventProperties.List.Web
- SPItemEventProperties.ListItem.Web
SPItemEventProperties implements IDisposable to clean up the SPSite it creates; the others do not. It is not yet clear
if the framework actually handles these correctly, so it may be safer to avoid these properties in favor of creating a new developer-owned SPSite object.
public override void ItemAdded(SPItemEventProperties properties) { using (SPSite site = new SPSite(properties.WebUrl)) { using(SPWeb web = site.OpenWeb()) { SPList list = web.Lists[properties.ListId]; SPListItem item = list.GetItemById(properties.ListItemId); // Process item instead of properties.ListItem } } base.ItemAdded(properties); }
Microsoft.SharePoint.Portal.WebControls.IPersonalPage
(MOSS 2007)
- IPeronsalPage.PersonalSite
- IPersonalPage.PersonalWeb
My Site pages, which implement IPersonalPage
, implement these properties as shared instances that should not be disposed by controls that use them.
IPersonalPage currentMySitePage = this.Page as IPersonalPage; if (currentMySitePage != null && !currentMySitePage.IsProfileError) { SPSite personalSite = currentMySitePage.PersonalSite; // Process personalSite // NO personalSite.Dispose() }
Miscellaneous
- UnsecuredLayoutsPage.Web (and LayoutsPageBase.Web)
- SPControl.GetContextWeb()
- SPControl.GetContextSite()
- SPWebProvisioningProperties.Web
Objects that might be owned by the developer:
SPWeb.ParentWeb
This property will allocate an SPWeb object the first time it is called. The caveat is that once it is disposed, any reference to the property will return the disposed object. If an SPWeb is not owned by the developer, its ParentWeb should be considered not owned as well. For example, there could be a problem if two components both depend on SPContext.Current.Web.ParentWeb and one calls Dispose() before the other is done with it. Official Microsoft guidance is to never explicitly Dispose() ParentWeb.
Additional Resources
- Best Practices: Using Disposable Windows SharePoint Services Objects
by Scott Harris, Mike Ammerlaan, Stefan Goßner and Roger Lamb (Nov. 2006) (Updated Jan. 2009) - SharePoint 2007 and WSS 3.0 Dispose Patterns by Example
by Roger Lamb (Feb. 2008) (Updated Jan. 2009) - Disposing SPWeb and SPSite objects
by Stefan Goßner (Dec. 2008) - The New Definitive SPSite/SPWeb Disposal Article
by Keith Dahlby (Dec. 2008) - Troubleshooting SPSite/SPWeb leaks in WSS v3 and MOSS 2007
by Stefan Goßner (May 2008) - Dealing with Memory Pressure problems in MOSS/WSS
by Stefan Goßner (Nov. 2007) - Best Practices: Common Coding Issues When Using the SharePoint Object Model
by Scott Harris and Mike Ammerlaan (Sept. 2007) - SharePoint Dispose Checker highlights issues in project
by Daniel Brown (Feb 2009) - Diagnosing and Fixing SharePoint Out of Memory Exceptions by Bryan Dougherty










