Uno de los grandes problemas que tenemos los desarrolladores de SharePoint es el buen/mal uso que se realiza con diversos objetos como SPSite y SPWeb. La diferencia entre utilizar estos elementos correctamente o de forma errónea, hace que tu desarrollo funcione bien o mal. En este post vamos a analizar estos fallos y como poder solucionarlos.
¿Cuál es el problema con el uso de SPSite?
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 elemento del contexto SPContext: motivo hacemos el dispose de forma incorrecta y eliminamos lo que esta viendo el usuario
- Cuando definimos la variable: motivo no hacemos el dispose y ocurre el problema mencionado anteriormente
¿Cómo utilizar el SPContext?
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:
- Hemos asignado una referencia al contexto en una variable, con lo cual al liberar/disposar la varible eliminamos el contexto y por lo tanto la página Web.
- La opción no es quitar el Dispose porque estamos utilizando el Contexto, motivo de esta forma dejamos una variable SPSite sin liberar y que puede producir el caso mencionando anteriormente.
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.
Otros problemas que tenemos al utilizar el SPSite
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.
Resumen
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/