2010-04-17 21 views
5

Tengo un problema divertido en el que durante el apagado de la aplicación, los bloques try/catch se ignoran aparentemente en la pila.¿Cuándo es un try catch no un try catch?

No tengo un proyecto de prueba en funcionamiento (sin embargo, debido a la fecha límite, de lo contrario, intentaría reproducirlo totalmente), pero considere el siguiente fragmento de código.

class IndexNotFoundException : Exception { } 

public static string RunAndPossiblyThrow(int index, bool doThrow) 
{ 
    try 
    { 
     return Run(index); 
    } 
    catch(IndexNotFoundException e) 
    { 
     if(doThrow) 
      throw; 
    } 
    return ""; 
} 

public static string Run(int index) 
{ 
    if(_store.Contains(index)) 
     return _store[index]; 
    throw new IndexNotFoundException(); 
} 

public static string RunAndIgnoreThrow(int index) 
{ 
    try 
    { 
     return Run(index); 
    } 
    catch(IndexNotFoundException e) 
    { 
    } 
    return ""; 
} 

Durante el tiempo de ejecución, este patrón funciona estupendamente. Obtenemos soporte heredado para código que se basa en excepciones para control de programa (mal) y podemos seguir adelante y eliminar lentamente las excepciones utilizadas para el control de programa.

Sin embargo, al cerrar nuestra interfaz de usuario, vemos una excepción lanzada desde "Ejecutar" aunque "doThrow" es falso para TODOS los usos actuales de "RunAndPossiblyThrow". Incluso llegué a verificar esto modificando el código para que pareciera "RunAndIgnoreThrow" y sigo teniendo un cierre de la UI de la publicación de la falla.

Sr. Eric Lippert, leo su blog a diario, me encantaría escuchar que se trata de un error conocido y no me estoy volviendo loco.

EDITAR Esta es multi-hilo, y he verificado todos los objetos no se modifican mientras se accede

EDITAR explícitamente muestran excepción es la nuestra

EDITAR se olvidó de mencionar, esto es en el cierre y, lamentablemente, Visual Studio no puede detectar el bloqueo directamente. Es probable que falle en un hilo que no sea el de la interfaz de usuario, y una vez que se cierra, este se cierra. Solo pude depurar esto ejecutando repetidamente & cerrando la aplicación, con el administrador de tareas abierto, "Crear archivo volcado" y mirando el desorden resultante de 400 mb en Windbg. Win7 64 para referencia. Asegúrate de que esto tenga sentido para ti.

EDITAR

El siguiente código al cerrar el sistema sigue mostrando la misma excepción.

class IndexNotFoundException : Exception { } 

public static string RunAndPossiblyThrow(int index, bool doThrow) 
{ 
    try 
    { 
     return Run(index); 
    } 
    catch 
    { 
    } 
    return ""; 
} 

public static string Run(int index) 
{ 
    if(_store.Contains(index)) 
     return _store[index]; 
    throw new IndexNotFoundException(); 
} 

La única cosa que parece deshacerse de la excepción es ir directamente a

class IndexNotFoundException : Exception { } 

public static string RunAndPossiblyThrow(int index, bool doThrow) 
{ 
    try 
    { 
     return Run(index); 
    } 
    catch 
    { 
    } 
    return ""; 
} 

public static string Run(int index) 
{ 
    if(_store.Contains(index)) 
     return _store[index]; 
    return ""; 
} 

Naturalmente la excepción se ha ido, pero mis temor a volverse loco todavía están presentes.

EDITAR

sólo empeoró ... esto vuelve a colgarse ...

class IndexNotFoundException : Exception { } 

public static string RunAndPossiblyThrow(int index, bool doThrow) 
{ 
    try 
    { 
     throw new IndexNotFoundException(); 
    } 
    catch 
    { 
    } 
    return ""; 
} 

EDITAR tengo una clara sensación de que esto va a conseguirme ninguna parte. Además del comportamiento extraño, también puedo observar que durante la ejecución de la IU en el caso anterior, la captura de prueba se está ejecutando fielmente. Mi interfaz de usuario no se bloquea & está lleno de cadenas vacías. Sin embargo, una vez que empiezo a cerrar la interfaz de usuario, se muestra el bloqueo y la captura de prueba ya no detiene la excepción.

EDITAR & última Al parecer, el archivo de volcado fue la inclusión en el más reciente excepción de primera oportunidad. Lo verifiqué creando un nuevo proyecto que arrojó dentro de una captura de prueba & durmió durante 10 segundos. Durante la espera obtuve el.dmp archivo &, mi excepción completamente atrapada estaba apareciendo.

voy a marcar algunos puntos para las respuestas útiles, sin embargo, lamentablemente todavía no hay rima o razón por la que mi código está fallando ...

+1

¿Se puede publicar la información de la excepción? ¿Seguimiento de pila, tipo de excepción, mensaje, etc.? – Jake

+0

La excepción es una excepción IndexNotFound de plano-jane que hemos creado en nuestro proyecto. No se arroja nada del código administrado, es nuestra excepción y nuestra pila como se describe en la pregunta. Voy a actualizar la pregunta. – Dearmash

+0

¿Este "bloqueo" es en realidad un mensaje de excepción, con un seguimiento de pila, o es un diálogo de bloqueo de Windows? – Aaronaught

Respuesta

3

Existen varias excepciones que no pueden detectarse. Stack Overflow en particular! ¿Podría uno de estos estar ocurriendo en algún lugar de tu código?

Ver http://www.bluebytesoftware.com/blog/PermaLink,guid,223970c3-e1cc-4b09-9d61-99e8c5fae470.aspx

+0

Este es un buen recurso. Desafortunadamente, estoy relativamente seguro de que cada una de estas excepciones todavía puede quedar atrapada en un depurador. Lamentablemente, ninguna cantidad de depurador me permite detectar lo que esté cayendo. Parece un blog decente, buena cantidad de contenido, si no se actualiza más de 1/mes. Lo agregaré a la lista. Gracias, – Dearmash

0

Ha intentado añadir una cláusula "por fin"? solo para ver si no ignorará el try/catch por completo? En teoría, siempre debería saltar a esa línea antes de que salga del try/catch pase lo que pase.

Si todavía ignora eso, entonces hay algo definitivamente extraño al respecto.

0

Probablemente atrape y arroje de nuevo alguna otra excepción de Ejecutar. Probablemente _store es nulo o algo así.

+0

Lea la descripción, la excepción es el tipo esperado. – Dearmash

4

Agregue una excepción como una captura extra. Creo que recibes alguna otra excepción que ApplicationException y esa es la que bloquea tu aplicación.

+0

He dicho antes, quiero que otras excepciones sean excepciones y crash. Esta es nuestra excepción que estoy buscando y faltante. – Dearmash

+0

Bueno, y otras excepciones son, y están bloqueando su aplicación. –

+0

en el archivo .dmp resultante, la única excepción que se incluye es mi excepción. No estoy seguro de lo mucho más claro que puedo ser. – Dearmash

0

Un par de cosas que pueden ayudar con el diagnóstico:

  • Registro de AppDomain.CurrentDomain.UnhandledException para que pueda ver si algo está fallando en un subproceso distinto del subproceso de interfaz de usuario

  • Inscríbase Application.ThreadException para capturar cualquier excepción que no esté atrapada en el subproceso UI

  • Como esto ocurre durante el apagado, ¿está utilizando Finalizadores que podrían arrojar el resultado final? ¿hilo izer?

+0

Ambos manejadores están registrados y ninguno está siendo golpeado. De lo contrario, esto habría sido solo una simple cuestión de analizar nuestros registros. La vida se volvió mucho más fácil el día que agregué esos controladores al código. Que yo sepa, no declaramos explícitamente ningún finalizador en nuestro código. Confiamos en que IDspose bastante para eliminar las cosas una vez que hayamos terminado con ellas. – Dearmash

+0

Puede buscar hilos que vayan mucho más allá del inicio de la aplicación, aunque me sorprendería si AppDomain libera sus controladores UnhandledException antes de que todos los hilos finalicen. –