Pergunta

I have used something like

 using (SPWeb web = SPControl.GetContextWeb(Context))

but while deploying the project it shows an error. While trying to figure out the cause I came across an msdn article:

http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.webcontrols.spcontrol.getcontextweb.aspx

which states this:

Do not use the Dispose or Close method of the SPWeb class to close the object returned through the GetContextWeb method. Instead let Windows SharePoint Services or your portal application manage the object.

I am new to SharePoint, can anyone explain me the reason behind this?

Foi útil?

Solução

IF you get the SPWeb from the Context, it has been created elsewhere, and that elsewhere will destroy it for you.

If you destroy (Dispose) it too early, when the page comes to Dispose of it, it'll most likely panic, and some data used to generate the page will probably be lost.

Rule of thumb - if you use SPSite.OpenWeb() or otherwise use new SPWeb(), then you have to Dispose of it yourself (or include in a using statement). This applies equally for webs retrieved via a SPWebCollection (e.g. SPWeb.Webs, SPSite.AllWebs or SPWeb.GetSubwebsForCurrentUser()).

Outras dicas

The Dispose() method if the IDisposal interface is a specifc interface that is used when object locks heavy and expensive resources. For instance when you're acquiring a connection to a database. The Dispose method is there to tell the object that I'm done with the connection (in the Sql case) and that you can now close it and let someone else use the resource. In .NET everything is written in managed code and automatically garbage collected, whereas SQL connections and COM+ objects are not automatically released.

In the case of SharePoint it has been a discussion (for years now) on when and how to dispose objects. James explains it well with the rule of thumb. The reason you need to call Dispose in some cases is that SharePoint uses non-managed code (COM+) in SPSite and SPWeb objects to for instance make database calls. If the objects are not disposed properly you will eventually run out of memory since the garbage collector in .NET cannot automatically release the "external" (to .NET) objects.

In your case you should not use the using statement since it will automatically dispose the object. The using statement is expanded like this in the compiler, from

using (SPWeb web = SPControl.GetContextWeb(Context)) {
    ...
}

to this:

try (SPWeb web = SPControl.GetContextWeb(Context)) {
    ...
}
finally {
    web.Dispose();
}

I am getting up to speed with SharePoint development as well and found Dispose Patterns By Example to be a great reference on this subject. Hope this helps you as much as it's helped me.

If you are in doubt as to whether or not you are handling the dispose correctly, Microsoft has the SPDisposeCheck tool available to check it for you. You can run this manually, directly from Visual Studio or even incorporate it into the validation on your build server.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a sharepoint.stackexchange
scroll top