exception - ¿Por qué se cierra mi grupo de aplicaciones IIS7 después de una excepción en una DLL llamada desde una página ASP.NET?
iis-7 application-pool (2)
He leído el problema de cierre del grupo de aplicaciones ASP.NET e IIS 7.5: problema con el grupo de aplicaciones pero no respondieron mi pregunta.
Tengo una página C # ASP.NET que en el código subyacente crea una instancia de una clase desde una DLL suministrada a través del directorio BIN, y luego llama a un método en esta instancia. El método dentro de la DLL lanza la System.ArgumentException
debido a una columna no existente en un objeto DataRow
. El registro de eventos muestra el siguiente error:
Source: ASP.NET 2.0.50727.0
Application ID: /LM/W3SVC/1/ROOT/...
Process ID: 9476
Exception: System.ArgumentException
Message: Column ''someColumn'' does not belong to table.
StrackTrace:
El código de llamada en la página ASP.NET envuelve la llamada al método en un bloque genérico try-catch
. Cuando solicito la página, esto bloquea el grupo de aplicaciones correspondiente de mi instancia de IIS y mi sitio web ya no está disponible (Error 503). Tengo que reiniciar manualmente el grupo de aplicaciones y el sitio funciona de nuevo.
Actualizar Según lo solicitado, el bloque try catch
del código ASP.NET detrás:
try
{
SomeExternalClass someExternalClass = new SomeExternalClass();
someExternalClass.SomeMethod( someId );
}
catch( Exception ex )
{
// "smp" is an instance of "StatusMessagePanel", a control we use on all pages
// to show error information, basically a div container with an icon.
smp.ShowError( ex.Message );
}
Ahora mi pregunta es ¿por qué una excepción relativamente "simple", como la excepción System.ArgumentException
se produce al intentar acceder a una columna DataRow
no existente, bloquea todo el sitio web? ¿El bloque de try-catch
genérico de la página ASP.NET tampoco ayuda, ni debería ser esta la razón para hacer que todo el sitio web no esté disponible, o es una suposición errónea? Nunca hubiera pensado que esto básicamente puede acabar con el servidor (II).
Antes de que la gente me diga que debería verificar la existencia de una columna antes de acceder a ella: lo sé y ahora se ha cambiado el código heredado, pero esta no es mi pregunta como se describe anteriormente, me gustaría saber por qué Las consecuencias son tan drásticas.
Actualización 2
El método en cuestión al que se llama dentro de la DLL inicia un hilo envuelto en un bloque try-catch
:
[...]
try
{
ThreadStart starter = () => CreateReport(...)
Thread thread = new Thread( starter );
thread.Start();
if( !thread.Join( TimeSpan.FromMinutes( 15 ) ) )
{
// Log some timeout warning
}
else
{
// Log information about successful report generation
}
}
catch( Exception ex )
{
// Log error information
}
Lo más probable es que su grupo de aplicaciones se esté cerrando automáticamente por la función de protección rápida contra fallas de IIS , como se señala en las preguntas vinculadas. Si verifica su registro de eventos, puede haber múltiples excepciones no controladas que se lanzan en rápida sucesión.
En pocas palabras, suficientes excepciones no controladas en un intervalo de tiempo configurable (el valor predeterminado es 5 en 5 minutos) cerrarán el AppPool, lo que provocará la respuesta del Servicio 503 No Disponible.
El razonamiento detrás de esta función es que si tiene una aplicación defectuosa, es probable que no desee que se reinicie automáticamente en cada solicitud posterior, consumiendo recursos y posiblemente dañando los datos.
Tengo que admitir que este no es el comportamiento "predeterminado" que yo hubiera esperado tampoco.
Echa un vistazo a la explicación de Rick Stahls , es un poco más en profundidad.
Para solucionar esto realmente, debe capturar la excepción o evitar que se lance la excepción (como sugiere @leppie). Se supone que las excepciones no controladas destruyen todo el proceso de ejecución (lo que significa que solo el proceso de solicitud / trabajo, no IIS) hace que el código .Net sea mucho más fácil de depurar, porque no oculta los errores o simplemente bloquea la aplicación.
Tenga en cuenta que esto se cambió en .Net 2.0:
http://msdn.microsoft.com/en-us/library/ms228965.aspx
http://support.microsoft.com/kb/911816
Actualizar
Basándome en su actualización anterior, no creo que su excepción sea realmente detectada, si es lanzada desde CreateReport()
. Ese método se está ejecutando en un hilo separado:
Necesita un try-catch en el cuerpo de CreateReport()
si aún no lo hay:
public static void CreateReport() {
try {
throw new Exception("reducto");
} catch {
Console.WriteLine("done did.");
}
}
Me pasó una vez. El error real (en mi caso) fue un desbordamiento de pila que estaba cerrando el grupo.
Parece que IIS se estaba protegiendo de consumir demasiados recursos.
Encontré el problema usando DebugDiag.
Aquí es donde comencé: http://www.webdebug.net/index.php/2012/12/collect-iis-crash-dump-with-debugdiag/
Me gustaría entender por qué una excepción en una DLL externa puede hacer que el grupo de aplicaciones IIS se cierre, incluso si la excepción está siendo detectada dentro de la DLL y también al llamar al método DLL desde el código que se encuentra detrás de la página ASP.NET .
La dll externa también se ejecuta en su grupo de aplicaciones. Un fallo importante en esta dll también colapsará su grupo de aplicaciones. Algunas excepciones no se pueden manejar y la excepción de es una de ellas. El tema se discute here . Tal vez sea lo que pasa en tu caso.