Using clause use to dispose common SharePoint objects like SPWeb and SPSite. This is an important issue for production environments, since not correctly disposing objects will result in excessive memory and resource usage, while over-disposing can lead to error spamming in the SharePoint log files.
Following are
some of the best Practice for disposing objects in SharePoint Development
Best
Practice #1: Use the Using Clause for all Sharepoint objects
that implement the IDisposable interface
Example
C# Coding
String
str;
using(SPSite
oSPsite = new SPSite("http://server"))
{
using(SPWeb
oSPWeb = oSPSite.OpenWeb())
{
str = oSPWeb.Title;
str = oSPWeb.Url;
}
}
Best
Practice #2: Use the
try/catch/finally blocks. When you use try blocks, it is important to add a
finally block to ensure that all objects are disposed off properly:
Example
C# Coding
String
str;
SPSite
oSPSite = null;
SPWeb
oSPWeb = null;
try
{
oSPSite
= new SPSite("http://server");
oSPWeb
= oSPSite.OpenWeb(..);
str
= oSPWeb.Title;
}
catch(Exception
e)
{
}
finally
{
if
(oSPWeb != null)
oSPWeb.Dispose();
if
(oSPSite != null)
oSPSite.Dispose();
}
Best
Practice #3: Using Response.Redirect
in the try block will never execute the finally block, so it is important, to
dispose off all objects before the redirection occurs:
Example
C# Coding
String
str;
SPSite
oSPSite = null;
SPWeb
oSPWeb = null;
bool
bDoRedirection = true;
try
{
oSPSite
= new SPSite("http://server");
oSPWeb
= oSPSite.OpenWeb(..);
str
= oSPWeb.Title;
if(bDoRedirection)
{
if (oSPWeb != null)
oSPWeb.Dispose();
if (oSPSite != null)
oSPSite.Dispose();
Response.Redirect("newpage.aspx");
}
}
catch(Exception
e)
{
}
finally
{
if
(oSPWeb != null)
oSPWeb.Dispose();
if
(oSPSite != null)
oSPSite.Dispose();
}
Best
Practice #4: Whenever you create an
object with a new operation, the creating application must dispose it off
Example
C# Coding
SPSite
oSPSite = new SPSite("http://server");
...
do some task ...
oSPSite.Dispose();
Or by using clause
using(SPSite
oSPSite = new SPSite("http://server"))
{
...
do some task ...
}
Best
Practice #5: For Site.OpenWeb method,
you need to dispose it off explicitly.
Example
C# Coding
String
str;
SPSite
oSPSite = new SPSite("http://server");
SPWeb
oSPWeb = oSPSite.OpenWeb();
str
= oSPWeb.Title;
str
= oSPWeb.Url;
...
do some task ...
oSPWeb.Dispose();
oSPSite.Dispose();
Or by using clause
String
str;
using(SPSite
oSPSite = new SPSite("http://server"))
{
using(SPWeb
oSPWeb = oSPSite.OpenWeb())
{
str = oSPWeb.Title;
str = oSPWeb.Url;
...
do some task ...
}
}
Best
Practice #6: An exception to the rule
is that One should not explicitly dispose SPSite.RootWeb, as it is
automatically disposed off.
Similarly
one should not explicitly dispose SPContext.Current.Site and SPContext.Current.Web as
they are handles automatically by Sharepoint and .NET framework.
Example
C# bad Coding Practice
void
SPContextBADPractice()
{
SPSite
siteCollection = SPContext.Current.Site;
siteCollection.Dispose();
// DO NOT DO THIS
SPWeb
web = SPContext.Current.Web;
web.Dispose(); // DO NOT DO THIS
}
Example
C# good Coding Practice
void
SPContextBestPractice()
{
SPSite
siteCollection = SPContext.Current.Site;
SPWeb
web = SPContext.Current.Web;
//
Do NOT call Dispose()
}
Best
Practice #7: SPControl.GetContextSite(Context)
and GetContextWeb(Context) return SPSite and SPWeb respectively, they do not
need an explicit call to Dispose(), they will be disposed automatically
Example
C# bad Coding Practice
void
SPControlBADPractice()
{
SPSite
siteCollection = SPControl.GetContextSite(Context);
siteCollection.Dispose(); //
DO NOT DO THIS
SPWeb
web = SPControl.GetContextWeb(Context);
web.Dispose(); //
DO NOT DO THIS
}
Example
C# good Coding Practice
void
SPControlBestPractice()
{
SPSite
siteCollection = SPControl.GetContextSite(Context);
SPWeb
web = SPControl.GetContextWeb(Context);
//
Do NOT call Dispose()
}
Best
Practice #8: SPWeb.ParentWeb
returns SPWeb, and needs to be disposed off explicitly using either Dispose()
or the using clause
Example
C# bad Coding Practice
void
ParentWebLeak()
{
using
(SPSite siteCollection = new SPSite("http://moss"))
{
using (SPWeb outerWeb = siteCollection.OpenWeb())
{
SPWeb parentWeb = outerWeb.ParentWeb; // Internal reference to SPWeb parentWeb
string sTitle = parentWeb.Title;
string sUrl = parentWeb.Url;
//
SPWeb object parentWeb leaked
} // SPWeb object outerWeb.Dispose() automatically called
}
// SPSite object siteCollection.Dispose() automatically called
}
Example
C# good Coding Practice
void
ParentWebBestPractice()
{
using
(SPSite siteCollection = new SPSite("http://moss"))
{
using (SPWeb outerWeb = siteCollection.OpenWeb())
{
using (SPWeb parentWeb = outerWeb.ParentWeb) // Internal reference to SPWeb
parentWeb
{
string sTitle = parentWeb.Title;
string sUrl = parentWeb.Url;
} // SPWeb object parentWeb.Dispose() automatically called
} // SPWeb object outerWeb.Dispose() automatically called
}
// SPSite object siteCollection.Dispose() automatically called
}
Best
Practice #9: SPWeb.Webs returns an
SPWeb object, practically used in drilling down sub-sites within a Site
Example
C# bad Coding Practice
void
WebsLeak()
{
using
(SPSite siteCollection = new SPSite("http://moss"))
{
using (SPWeb outerWeb = siteCollection.OpenWeb())
{
foreach (SPWeb innerWeb in outerWeb.Webs)
{
//
SPWeb innerWeb leak
}
} // SPWeb object outerWeb.Dispose() automatically called
}
// SPSite object siteCollection.Dispose() automatically called
}
Example
C# good Coding Practice
void
WebsBestPractice()
{
using
(SPSite siteCollection = new SPSite("http://moss"))
{
using (SPWeb outerWeb = siteCollection.OpenWeb())
{
foreach (SPWeb innerWeb in outerWeb.Webs)
{
innerWeb.Dispose();
}
} // SPWeb object outerWeb.Dispose() automatically called
}
// SPSite object siteCollection.Dispose() automatically called
}
Best
Practice #10: AllWebs[] Indexer returns SPWeb
object that needs to be disposed to avoid
aggregation of memory which
can lead to memory pressure when running on a
site collection with
large number of sub sites. Practically used in
Enumerating or iterating all webs in a site collection.
Example
C# bad Coding Practice
void
AllWebsForEachLeakBestPractices()
{
using
(SPSite siteCollection = new SPSite("http://moss"))
{
using (SPWeb outerWeb = siteCollection.OpenWeb())
{
foreach (SPWeb innerWeb in siteCollection.AllWebs)
{
// Explicit Dispose must be called to avoid
aggregation of memory
}
} // SPWeb object outerWeb.Dispose() automatically called
}
// SPSite object siteCollection.Dispose() automatically called
}
Example
C# good Coding Practice
void
AllWebsForEachLeakBestPractices()
{
using
(SPSite siteCollection = new SPSite("http://moss"))
{
using (SPWeb outerWeb = siteCollection.OpenWeb())
{
foreach (SPWeb innerWeb in siteCollection.AllWebs)
{
innerWeb.Dispose(); // Explicit Dispose must be called to avoid
aggregation of memory
}
} // SPWeb object outerWeb.Dispose() automatically called
}
// SPSite object siteCollection.Dispose() automatically called
}
Example
C# bad Coding Practice
void
AllWebsIndexerLeak()
{
using
(SPSite siteCollection = new SPSite("http://moss"))
{
SPWeb web = siteCollection.AllWebs[0];
// SPWeb web
leaked
}
// SPSite object siteCollection.Dispose() automatically called
}
Example
C# good Coding Practice
void
AllWebsIndexerBestPractice()
{
using
(SPSite siteCollection = new SPSite("http://moss"))
{
using (SPWeb web = siteCollection.AllWebs[0])
{
} // SPWeb object web.Dispose() automatically called
}
// SPSite object siteCollection.Dispose() automatically called
}
Best
Practice #11: AllWebs.Add() returns a instance of SPWeb object which needs to be disposed.
Example
C# bad Coding Practice
void
AllWebsAddLeak()
{
using
(SPSite siteCollection = new SPSite("http://moss"))
{
SPWeb web = siteCollection.AllWebs.Add("site-relative URL");
// SPWeb web
Leaked
}
// SPSite object siteCollection.Dispose() automatically called
}
Example
C# good Coding Practice
void
AllWebsAddBestPractice()
{
using
(SPSite siteCollection = new SPSite("http://moss"))
{
using (SPWeb web = siteCollection.AllWebs.Add("site-relative URL"))
{
} // SPWeb object web.Dispose() automatically called
}
// SPSite object siteCollection.Dispose() automatically called
}
Best
Practice #12: OpenWeb() returns
a SPWeb object which needs to be disposed.
Example
C# bad Coding Practice
void
OpenWebLeak()
{
using
(SPWeb web = new SPSite(SPContext.Current.Web.Url).OpenWeb())
{
//
SPSite leaked !
}
// SPWeb object web.Dispose() automatically called
}
Example
C# good Coding Practice
void
OpenWebBestPractice()
{
using
(SPSite siteCollection = new SPSite("http://moss"))
{
using (SPWeb web = siteCollection.OpenWeb())
{
} // SPWeb object web.Dispose() automatically called
}
// SPSite object siteCollection.Dispose() automatically called
}
Best
Practice #13:new SPSite() -
Instantiating SPSite objects
with the new operator needs to be disposed.
Example
C# bad Coding Practice
void
CreatingSPSiteLeak()
{
SPSite
siteCollection = new SPSite("http://moss");
//
siteCollection leaked
}
Example
C# good Coding Practice
void
CreatingSPSiteExplicitDisposeBestPractice()
{
SPSite
siteCollection = new SPSite("http://moss");
siteCollection.Dispose();
}
void
CreatingSPSiteWithAutomaticDisposeBestPractice()
{
using
(SPSite siteCollection = new SPSite("http://moss"))
{
}
// SPSite object siteCollection.Dispose() automatically called
}
Thank you very
much
Fahadullah Karimi
SharePoint Specialist
List of all web parts used on SharePoint 2013 pages using PowerShell | How to Save Site as Template in Publishing Site Template in SharePoint 2013 |