Sunday, 29 June 2014

SPContext.Current.Site and SPSite

The only time you should dispose SPSite and SPWeb objects in when you created them yourself, like this
SPSite site = new SPSite("http://sp2010");
site.Dispose();
or use a using Statement to handle the cleanup for you.
using (SPSite site = new SPSite("http://sp2010");
{
//do stuff here
}
When you use a using statement, whatever objects are created in it's initialization statement, will be automatically disposed for you when the using block is done executing.
When you are working with SPContext Object , there is no need to dispose following Object
1. SPContext.Current.Site
2. SPContext.Current.Site.RootWeb
Best practice:
public void RootWeb()
{
// New SPSite.
using (SPSite siteCollection = new SPSite("http://sp2010"))
{
using (SPWeb outerWeb = siteCollection.OpenWeb())
{
//Your code goes here
}
}
// SPContext and SPControl
SPWeb rootWeb2 = SPContext.Current.Site.RootWeb;
// Also would apply to SPControl.GetContextSite(Context);
// No explicit rootWeb2 dispose required because it's obtained from SPContext.Current.Site.
}
-------------------------------
if you do like this memory will leak
void CombiningCallsLeak()
{
using (SPWeb web = new SPSite(SPContext.Current.Web.Url).OpenWeb())
{
// ... New SPSite will be leaked.
} // SPWeb object web.Dispose() automatically called.
}
How can we solve memory leak?
void CombiningCallsBestPractice()
{
using (SPSite siteCollection = new SPSite(SPContext.Current.Web.Url))
{
using (SPWeb web = siteCollection.OpenWeb())
{
//Perform operations on site.
} // SPWeb object web.Dispose() automatically called.
} // SPSite object siteCollection.Dispose() automatically called.
}
Or
void CombiningCallsBestPractice()
{
using (SPSite siteCollection = new SPSite(SPContext.Current.Web.Url))
using (SPWeb web = siteCollection.OpenWeb())
{
//Perform operations on site.
} // SPWeb object web.Dispose() automatically called; SPSite object
// siteCollection.Dispose() automatically called.
}
Or using Try catch
String str;
SPSite oSPSite = null;
SPWeb oSPWeb = null;
try
{
oSPSite = new SPSite("http://server");
oSPWeb = oSPSite.OpenWeb(..);
str = oSPWeb.Title;
}
catch(Exception e)
{
//Handle exception, log exception, etc.
}
finally
{
if (oSPWeb != null)
oSPWeb.Dispose();
if (oSPSite != null)
oSPSite.Dispose();
}
Or using statement
public static void SPSiteCollectionForEachBestPractice()
{
string sUrl = "http://spvm";
using (SPSite siteCollectionOuter = new SPSite(sUrl))
{
SPWebApplication webApp = siteCollectionOuter.WebApplication;
SPSiteCollection siteCollections = webApp.Sites;
SPSite siteCollectionInner = null;
foreach (siteCollectionInner in siteCollections)
{
try //Should be first statement after foreach.
{
Console.WriteLine(siteCollectionInner.Url);
//Exception occurs here.
}
finally
{
if(siteCollectionInner != null)
siteCollectionInner.Dispose();
}
}
}
} // SPSite object siteCollectionOuter.Dispose() automatically called.
}
--------------------------
Good coding
void CreatingSPSiteExplicitDisposeNoLeak()
{
SPSite siteCollection = null;
try
{
siteCollection = new SPSite("http://moss");
}
finally
{
if (siteCollection != null)
siteCollection.Dispose();
}
}
--------------------------
CreatingSPSiteWithAutomaticDisposeNoLeak()
{
using (SPSite siteCollection = new SPSite("http://moss"))
{
} // SPSite object siteCollection.Dispose() is called automatically.
}
----------------------------------------
void OpenWebNoLeak()
{
using (SPSite siteCollection = new SPSite("http://moss"))
{
using (SPWeb web = siteCollection.OpenWeb())
{
} // SPWeb object web.Dispose() automatically called.
} // SPSite object siteCollection.Dispose() automatically called.
}