La clase SPSite la podemos definir como el objeto que tiene toda la información relativa a nuestro sitio Web. Este objeto tiene multitud de propiedades (Usuarios, Subsitios, Tipos de Contenido, Columnas de Sitio, etc). Cada vez que declaramos una variable de este tipo y la instanciamos a un proceso en el IIS, se queda a la escucha de utilizarlo. El problema radica en que si no eliminamos esta variable de memoria, se queda permanentemente en el IIS (hasta que este se reinicia). El resultado es que la navegación sobre la página cada vez va peor hasta que el sitio Web cae.
Miremos un caso gráfico a modo de ejemplo: implemento un menú de SharePoint, en este menú no he eliminado el SPSite de la consulta sobre el nodo de navegación. ¿Sabéis qué ocurre si tenemos más de 500 visitas concurrente? No hay que ser muy lince para saber que el sistema se caerá.
Cuando utilizamos el SPSite tenemos principalmente dos problemas:
Cuando utilizamos el SPContext tenemos que ser conscientes de que no lo podemos Disposar y también no Disposar una variable a la que hemos asignado el contexto.
Mala práctica
SPSite spSite= SPContext.Current.Site; ... ... spSite.Dispose();
Hay dos motivos por los que está mal:
Buena práctica:
SPSite spSite= new SPSite(SPContext.Current.Site.ID); .... .... spSite.Dispose();
Mejor aún es utilizarla haciendo uso del Using:
using(SPSite spSite=new SPSite(SPContext.Curre.Site.ID)) { ... ... }
¿ Cuándo utilizar el SPContext/cuándo definir una variable nueva?
Por regla general siempre que se pueda utilizamos el SPContext, principalmente porque es mucho más rápido e impacta menos en el performance del desarrollo.
Cuando utilizamos el Foreach, por regla general no solemos hacer el dispose de la variable que esta dentro del Foreach. Motivo: si vemos la definición que tiene el lenguaje C# es que todos los elemento que implementen el IEnumerable se ejecuta el método Dispose antes de pasar al siguiente elemento. ¿Qué ocurre en SharePoint? Que las colecciones de SPSite no implementan este método por lo que cuando las recorremos en un foreach no hace el dispose. Con lo cual se puede imaginar el problema que podemos tener.
Mala práctica:
using (SPSite siteCollectionOuter = new SPSite("http://moss")) { SPWebApplication webApp = siteCollectionOuter.WebApplication; SPSiteCollection siteCollections = webApp.Sites; foreach (SPSite siteCollectionInner in siteCollections) { } } //
Buena práctica:
using (SPSite siteCollectionOuter = new SPSite("http://moss")) { SPWebApplication webApp = siteCollectionOuter.WebApplication; SPSiteCollection siteCollections = webApp.Sites; foreach (SPSite siteCollectionInner in siteCollections) { try { // ... } finally { if(siteCollectionInner != null) siteCollectionInner.Dispose(); } } } // SPSite object siteCollectionOuter.Dispose() automatically called.
Muchas veces acusamos a un producto de un mal funcionamiento en lugar de comprobar o verificar lo que estamos haciendo. SharePoint, como todo producto/lenguaje, tiene sus reglas y debemos cumplirlas si queremos que nuestros desarrollos funcionen a la perfección. SharePoint en algunos aspectos es un poco diferente a otros lenguajes, esto no lo hace ni mejor ni peor producto, pero debemos conocerlo si queremos hacer desarrollos de calidad.
Referencias
http://david-martos.blogspot.com.es/2011/01/spcontext-using-runwithelevatedprivileg.html
https://msdn.microsoft.com/en-us/library/aa973248.aspx#sharepointobjmodel__spsiteobjects
http://www.csharphelp.com/2007/09/the-internals-of-c-foreach/
Este sitio web utiliza cookies para que tengas la mejor experiencia de usuario. Si continuas navegando, estás dando tu consentimiento para aceptar las cookies y también nuestra política de cookies (esperemos que no te empaches con tanta cookie 😊)