Eliminación y cierre de objetos SPWeb
Pregunta
He usado algo como
using (SPWeb web = SPControl.GetContextWeb(Context))
pero al implementar el proyecto muestra un error.Mientras intentaba descubrir la causa, encontré un artículo de MSDN:
que dice esto:
No utilice el método Dispose o Close de la clase SPWeb para cerrar el objeto devuelto mediante el método GetContextWeb.En su lugar, deje que Windows SharePoint Services o su aplicación de portal administren el objeto.
Soy nuevo en SharePoint, ¿alguien puede explicarme el motivo de esto?
Solución
Si obtienes el Spweb del contexto, se ha creado en otro lugar, y eso en otro lugar lo destruirá por ti.
Si lo destruye (elimina) demasiado temprano, cuando la página llega a deshacerse de ella, lo más probable es que se asuste, y algunos datos utilizados para generar la página probablemente se perderán.
Regla general: si usa spsite.openweb () o usa nuevo spweb (), entonces debe deshacerse de él usted mismo (o incluir en una declaración de uso). Esto se aplica igualmente para las redes recuperadas a través de una SpWebCollection (por ejemplo, SpWeb.WEBS, SPSITE.ALLWEBS o SPWEB.GETSubWEBSFORCURRENTUSER ()).
Otros consejos
El Dispose()
método si el IDisposal
La interfaz es una interfaz específica que se utiliza cuando un objeto bloquea recursos pesados y costosos.Por ejemplo, cuando adquiere una conexión a una base de datos.El método Dispose está ahí para decirle al objeto que terminé con la conexión (en el caso de Sql) y que ahora puede cerrarla y permitir que otra persona use el recurso.En .NET, todo está escrito en código administrado y se recolecta automáticamente la basura, mientras que las conexiones SQL y los objetos COM+ no se liberan automáticamente.
En el caso de SharePoint ha habido una discusión (desde hace años) sobre cuándo y cómo deshacerse de los objetos.James lo explica bien con la regla general.La razón por la que necesita llamar a Dispose en algunos casos es que SharePoint usa código no administrado (COM+) en SPSite
y SPWeb
objetos para, por ejemplo, realizar llamadas a bases de datos.Si los objetos no se eliminan correctamente, eventualmente se quedará sin memoria ya que el recolector de basura en .NET no puede liberar automáticamente los objetos "externos" (a .NET).
En tu caso deberías no utilizar el using
declaración ya que eliminará automáticamente el objeto.La declaración de uso se expande así en el compilador, desde
using (SPWeb web = SPControl.GetContextWeb(Context)) {
...
}
a esto:
try (SPWeb web = SPControl.GetContextWeb(Context)) {
...
}
finally {
web.Dispose();
}
También me pongo al día con el desarrollo de SharePoint y encontré Deseche patrones por ejemplo ser una gran referencia sobre este tema. Espero que esto te ayude tanto como me ha ayudado.
Si tiene dudas sobre si está manejando o no la eliminación correctamente, Microsoft tiene el Herramienta spdisposeCheck Disponible para comprobarlo por usted. Puede ejecutar esto manualmente, directamente desde Visual Studio o incluso incorporarlo en la validación de su servidor de compilación.