Just about any developer working long enough with
SharePoint will, at some point, wake up in the middle of the night with the
words "Memory Leak" echoing in through their head... No - it is not the cat's
fault, and no it does not mean you forgot to take out the trash again... What
did happen? You came across one of Microsoft's "best practices" articles
regarding disposing of SPWeb and SPSite objects in SharePoint…
According to the original MS guidance, every SPWeb or
SPSite object you create (or get) that was not initiated within the page's
context (i.e. not SPContext.Current.Web and not SPControl.GetContextWeb(Context)
) must be disposed of.
It used to be that the "using" statement construct was
recommended to avoid forgetting to dispose… in other cases you'd put up a flag
and dispose of it at the end of your code's life cycle - either way was good
enough.
Being the "good guys" that we are, we went over and
updated all of our codes and components to match these guide lines.
And what happened? Every once in a while disposing these
objects would cause baffling errors such as: "Trying to use a SPWeb object that
has been closed or disposed and is no longer valid".
But hey, if we call SPContext.Current.Site.RootWeb - the
best practices guidelines said we have to dispose of it! Same goes for
SPContext.Current.Web.Site and SPContext.Current.Web.Site.RootWeb etc.
Recently I came across a great article by Roger Lamb
showing a few updates from Microsoft regarding these disposable objects and
recommendations.
So - pay close attention to these updates… it just might
help you sleep through the night!
* When making a call to
SPContext.Current.Web.Site.RootWeb - you now have to dispose only of the SPSite
object: SPContext.Current.Web.Site!
Basically, you should NOT dispose of the SPSite.RootWeb
object directly.
* When calling SPWeb.ParentWeb - you should NOT dispose
of the ParentWeb object!
* Same goes to SPList.ParentWeb - do NOT dispose of the
SPWeb object.
Other updates I found interesting (and frustrating)
are:
* Calling SPWeb.AllWebs collection requires you to
dispose of this collection object.
* Creating a new site by SPWeb.Webs.Add() - need to
dispose of the web object returned.
* Calling GetLimitedWebPartManager() method? It will
create a SPWeb object of its own and not dispose of it properly.
Please review the complete updated best practices guide
at MSDN here:
http://msdn.microsoft.com/en-us/library/aa973248.aspx
I hope Microsoft will release an update for this issue
soon.. Just thinking of all the code lines I wrote under the wrong best
practices article is making me dizzy...
|