Leaking RootWeb instance

Jul 25, 2008 at 2:36 PM
Edited Jul 25, 2008 at 2:42 PM
Your createLookupColumn() method leaks a SPWeb instance when you call the RootWeb property. You'd better wrap it up in a using statement like this:

 1: private static void createLookupColumn(SPWeb web, string sColumnDefinitionXml, string sColumnName)
 2: {
 3:     // delete the column if it exists already and is not yet in use..
 4:     attemptColumnDelete(web, sColumnName);
 5:  
 6:     SPFieldLookup lookupColumn = null;
 7:  
 8:     // now create the column from the CAML definition..
 9:     string sCreatedColName = web.Fields.AddFieldAsXml(sColumnDefinitionXml);
 10:  
 11:     lookupColumn = web.Fields.GetFieldByInternalName(sCreatedColName) as SPFieldLookup;
 12:  
 13:     SPWeb rootWeb = web.Site.RootWeb;
 14:     try
 15:     {
 16:         lookupColumn.LookupWebId = rootWeb.ID;
 17:         lookupColumn.Update();
 18:     }
 19:     finally
 20:     {
 21:         // RootWeb might create a new SPWeb instance.
 22:         // Make sure it is disposed when necessary
 23:         if (rootWeb != web)
 24:             rootWeb.Dispose();
 25:     }
 26: }
Mar 5, 2009 at 11:56 AM

Most of the code examples use something like this  that accomplishes the same thing...


 

 

using (SPWeb rootWeb = web.Site.RootWeb)

 

{

lookupColumn.LookupWebId = rootWeb.ID;

lookupColumn.Update();

}

            

 

Mar 5, 2009 at 1:21 PM

No, you must never use the using statement for disposing SPWeb instances obtained using the RootWeb property! This is because RootWeb doesn't always return a new SPWeb instance, but sometimes returns an existing instance. If you call Dispose on that instance, you break other code. My special Dispose construct was the preferred way to deal with this. However, Microsoft released an updated advistory on how to deal with RootWeb via Roger Lambs blog:

http://blogs.msdn.com/rogerla/archive/2008/10/04/updated-spsite-rootweb-dispose-guidance.aspx

What it comes down to is that you should never call Dispose on an SPWeb obtained from RootWeb. So my previous code sample shouldn't be used either.