Posibles errores debidos a la compilación dinámica de ASP.NET

Hoy vamos a hablar de algunos errores que nos pueden aparecer debido a la compilación dinámica de ASP.NET

En primer lugar, deberíamos entender qué es la compilación dinámica y cómo funciona.

Por defecto, ASP.NET realiza la compilación en dos casos: cuando la aplicación se ejecuta y no está cargada en memoria o ha sufrido algún cambio en algún fichero que esté dentro de la aplicación (aquí os dejo un artículo con la lista de ficheros https://msdn.microsoft.com/en-us/library/2wawkw1c(v=vs.100).aspx)

En ambos casos funciona de forma muy similar:

  • Compila la aplicación
  • Copia los ficheros en la carpeta de ficheros temporales de ASP.NET
  • Cargar la aplicación en el Application Domain.

La diferencia más reseñable que hay entre la compilación por primera vez y la que se hace cuando se detecta un cambio es que inhabilita la aplicación que hay en memoria por lo que la próxima vez que haya una petición actuaría del mismo modo que si fuese la primera vez.

Hay dos aspectos muy importantes que condicionan la compilación dinámica:

Batch

Este modo hace que ASP.NET que compile los assemblies agrupados. Lo que reduce considerablemente el número de librerías que hay en memoria y el tamaño total de las mismas. La contrapartida que tiene este modo es que la primera carga será lenta pero hace que se eliminen los retrasos en las ejecuciones posteriores.

Debug

Este modo debería estar desactivado en producción, ya que una de las cosas que hace es deshabilitar el modo Batch. Es un tema que da para mucho, pero no me voy a extender. Si queréis más
información la podéis encontrar aquí: https://blogs.msdn.com/b/tess/archive/2006/04/13/575364.aspx

Una vez sabemos los principios básicos de la compilación dinámica (en este artículo se trata con más detalle https://msdn.microsoft.com/en-us/library/ms366723(v=vs.100).aspx) podemos entender el motivo por el que nos salen estos errores.

Uno de los errores más comunes asociados a la compilación dinámica de ASP.NET es el de BC30560: nombre_componente' is ambiguous in the namespace 'nombre_namespace'

A grandes rasgos, lo que está ocurriendo es que se está intentando cargar el mismo assembly en el Application domain en más de una ocasión y al no poder diferenciarlos unívocamente por compartir el mismo nombre y namespace nos aparece el error y finaliza la carga de la aplicación.

Esta situación puede darse si al procesarse una petición de la aplicación esta no está cargada en memoria, por lo que comienza una compilación. Si justo en ese momento se realiza otra petición, al no estar cargada la aplicación en memoria, comenzaría otra compilación y tendríamos assemblies duplicados.

Para evitar esta situación ASP.NET bloquea todas las peticiones entrantes durante un periodo de tiempo para que se pueda finalizar la compilación. El problema puede venir si nuestra aplicación tarda más en compilarse que el tiempo en el que se bloquean las peticiones.

Para poder solucionarlo, podemos eliminar los ficheros temporales de ASP.NET y volver a cargar la aplicación para que vuelvan a generarse los ficheros temporales.  Otra opción sería la de deshabilitar el modo batch que haría que la aplicación tardase menos en la carga inicial:

 <compilation debug="false" batch="false" />

También podemos cambiar el parámetro numRecompilesBeforeAppRestart, que podría hacer que se redujese el número de veces que se produce el error.

 <compilation debug="false" numRecompilesBeforeAppRestart="50" />

Otro motivo puede ser que exista una referencia circular que esté provocando que se cargue el assembly referenciado tantas veces como veces esté referenciado.

La opción de Fixed name and Single Assembly en una aplicación que tiene muchos componentes (páginas, controles…) puede ser la causa de que la aplicación tarde mucho en compilarse, por lo que deshabilitar esta opción y desmarcar la opción  Allow this precompiled site to be updatable.

image

 

Espero que os sirva de ayuda.

- José Ortega Gutiérrez