¿Por qué la excepción .NET no es capturada por el bloque try / catch?

Estoy trabajando en un proyecto utilizando la biblioteca de analizadores ANTLR para C #. He construido una gramática para analizar un texto y funciona bien. Sin embargo, cuando el analizador se encuentra con un token ilegal o inesperado, lanza una de las muchas excepciones. El problema es que, en algunos casos (no todos), mi bloque try / catch no lo detectará y, en cambio, detendrá la ejecución como una excepción no controlada.

El problema para mí es que no puedo replicar este problema en ningún otro lugar que no sea mi código completo. La stack de llamadas muestra que la excepción definitivamente ocurre dentro de mi bloque try / catch (Exception). Lo único en lo que puedo pensar es que hay algunas llamadas de ensamblado ANTLR que ocurren entre mi código y el código que lanza la excepción y esta biblioteca no tiene la depuración habilitada, por lo que no puedo avanzar a través de ella. Me pregunto si los ensamblajes no depurables inhiben la propagación de excepciones. La stack de llamadas se ve así; Las llamadas de assembly externo están en Antlr.Runtime:

     Expl.Itinerary.dll! TimeDefLexer.mTokens () Line 1213 C #
     Antlr3.Runtime.dll! Antlr.Runtime.Lexer.NextToken () + 0xfc bytes 
     Antlr3.Runtime.dll! Antlr.Runtime.CommonTokenStream.FillBuffer () + 0x22c bytes   
     Antlr3.Runtime.dll! Antlr.Runtime.CommonTokenStream.LT (int k = 1) + 0x68 bytes
     Expl.Itinerary.dll! TimeDefParser.prog () Line 109 + 0x17 bytes C #
     Expl.Itinerary.dll! Expl.Itinerary.TDLParser.Parse (string Text = "", Expl.Itinerary.IItinerary Itinerary = {Expl.Itinerary.MemoryItinerary}) Línea 17 + 0xa bytes C #

El fragmento de código de la llamada más baja en Parse () se ve así:

try { // Execution stopped at parser.prog() TimeDefParser.prog_return prog_ret = parser.prog(); return prog_ret == null ? null : prog_ret.value; } catch (Exception ex) { throw new ParserException(ex.Message, ex); } 

Para mí, una cláusula catch (Exception) debería haber capturado cualquier excepción. ¿Hay alguna razón por la que no lo haría?

Actualización: rastreé el ensamblaje externo con Reflector y no encontré ninguna evidencia de que se haya enhebrado. El ensamblaje parece ser solo una clase de utilidad de tiempo de ejecución para el código generado de ANTLR. La excepción lanzada es del método TimeDefLexer.mTokens () y su tipo es NoViableAltException, que se deriva de RecognitionException -> Exception. Esta excepción se produce cuando el lexer no puede entender el siguiente token en la secuencia; en otras palabras, entrada inválida. Se SUPONE que esta excepción sucederá, sin embargo, debería haber sido capturada por mi bloque try / catch.

Además, el reenvío de ParserException es realmente irrelevante para esta situación. Esa es una capa de abstracción que toma cualquier excepción durante el análisis y la conversión a mi propia excepción ParserException. El problema de manejo de excepciones que estoy experimentando nunca llega a esa línea de código. De hecho, comenté la parte de “lanzar una nueva excepción ParserException” y todavía recibí el mismo resultado.

Una cosa más, modifiqué el bloque original try / catch en cuestión para capturar en su lugar la excepción NoViableAltException, eliminando cualquier confusión hereditaria. Todavía recibí el mismo resultado.

Una vez alguien sugirió que, a veces, VS está demasiado activo al capturar excepciones manejadas cuando está en el modo de depuración, pero este problema también ocurre en el modo de lanzamiento.

Hombre, todavía estoy perplejo! No lo había mencionado antes, pero estoy ejecutando VS 2008 y todo mi código es 3.5. El conjunto externo es 2.0. Además, algunas de mis subclases de código son una clase en el ensamblaje 2.0. ¿Podría una falta de coincidencia de versión causar este problema?

Actualización 2: pude eliminar el conflicto de la versión .NET al transferir partes relevantes de mi código .NET 3.5 a un proyecto .NET 2.0 y replicar el mismo escenario. Pude replicar la misma excepción no manejada cuando se ejecuta de manera consistente en .NET 2.0.

Me enteré de que ANTLR ha lanzado recientemente 3.1. Entonces, actualicé desde 3.0.1 y lo volví a intentar. Resulta que el código generado está un poco refactorizado, pero en mis casos de prueba se produce la misma excepción no controlada.

Actualización 3: He replicado este escenario en un proyecto de VS 2008 simplificado . Siéntete libre de descargar e inspeccionar el proyecto por ti mismo. He aplicado todas las grandes sugerencias, pero aún no he podido superar este obstáculo.

Si puede encontrar una solución alternativa, comparta sus hallazgos. ¡Gracias de nuevo!


Gracias, pero VS 2008 rompe automáticamente las excepciones no manejadas. Además, no tengo un diálogo Debug-> Exceptions. La NoViableAltException que se lanza tiene la intención y está diseñada para ser capturada por el código de usuario. Como no se detecta como se esperaba, la ejecución del progtwig se detiene inesperadamente como una excepción no controlada.

La excepción lanzada se deriva de Exception y no hay subprocesos múltiples en proceso con ANTLR.

Creo que entiendo el problema. La excepción está siendo detectada, el problema es la confusión sobre el comportamiento del depurador y las diferencias en la configuración del depurador entre cada persona que intenta reprocharlo.

En el tercer caso de su repro, creo que está recibiendo el siguiente mensaje: “NoViableAltException no fue manejada por el código de usuario” y una stack de llamadas que se parece a esto:

          [Código externo]    
     > TestAntlr-3.1.exe! TimeDefLexer.mTokens () Line 852 + 0xe bytes C #
         [Código externo] 
         TestAntlr-3.1.exe! TimeDefParser.prog () Línea 141 + 0x14 bytes C #
         TestAntlr-3.1.exe! TestAntlr_3._1.Program.ParseTest (string Text = "foobar;") Línea 49 + 0x9 bytes C #
         TestAntlr-3.1.exe! TestAntlr_3._1.Program.Main (string [] args = {string [0x00000000]}) Line 30 + 0xb bytes C #
         [Código externo] 

Si hace clic con el botón derecho en la ventana de la stack de llamadas y ejecuta, active el código externo para ver esto:

         Antlr3.Runtime.dll! Antlr.Runtime.DFA.NoViableAlt (int s = 0x00000000, Antlr.Runtime.IIntStream input = {Antlr.Runtime.ANTLRStringStream}) + 0x80 bytes   
         Antlr3.Runtime.dll! Antlr.Runtime.DFA.Predict (Antlr.Runtime.IIntStream input = {Antlr.Runtime.ANTLRStringStream}) + 0x21e bytes  
     > TestAntlr-3.1.exe! TimeDefLexer.mTokens () Line 852 + 0xe bytes C #
         Antlr3.Runtime.dll! Antlr.Runtime.Lexer.NextToken () + 0xc4 bytes 
         Antlr3.Runtime.dll! Antlr.Runtime.CommonTokenStream.FillBuffer () + 0x147 bytes   
         Antlr3.Runtime.dll! Antlr.Runtime.CommonTokenStream.LT (int k = 0x00000001) + 0x2d bytes  
         TestAntlr-3.1.exe! TimeDefParser.prog () Línea 141 + 0x14 bytes C #
         TestAntlr-3.1.exe! TestAntlr_3._1.Program.ParseTest (string Text = "foobar;") Línea 49 + 0x9 bytes C #
         TestAntlr-3.1.exe! TestAntlr_3._1.Program.Main (string [] args = {string [0x00000000]}) Line 30 + 0xb bytes C #
         [Nativo de la transición administrada]  
         [Gestionado para la transición nativa]  
         mscorlib.dll! System.AppDomain.ExecuteAssembly (string assemblyFile, System.Security.Policy.Evidence assemblySecurity, string [] args) + 0x39 bytes    
         Microsoft.VisualStudio.HostingProcess.Utilities.dll! Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly () + 0x2b bytes  
         mscorlib.dll! System.Threading.ThreadHelper.ThreadStart_Context (estado del objeto) + 0x3b bytes   
         mscorlib.dll! System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext operationContext, System.Threading.ContextCallback callback, estado del objeto) + 0x81 bytes    
         mscorlib.dll! System.Threading.ThreadHelper.ThreadStart () + 0x40 bytes

El mensaje del depurador le indica que una excepción que se origina fuera de su código (de NoViableAlt) pasa por el código que posee en TestAntlr-3.1.exe! TimeDefLexer.mTokens () sin ser manejado.

La redacción es confusa, pero no significa que la excepción no sea detectada. El depurador le está haciendo saber que el código que posee mTokens () “debe ser sólido para que esta excepción no se genere.

Cosas con las que jugar para ver cómo se ve esto para aquellos que no reprocharon el problema:

  • Vaya a Herramientas / Opciones / Depuración y desactive “Habilitar solo mi código (solo administrado)”. o la opción.
  • Vaya a Depurador / Excepciones y desactive “No manejado por el usuario” para Excepciones de tiempo de ejecución en lenguaje común.

Independientemente de si el ensamblaje ha sido comstackdo como una comstackción de lanzamiento, la excepción ciertamente debería ‘hacer burbujas’ a la persona que llama, no hay razón para que un ensamblaje que no se compile en modo de depuración tenga ningún efecto en eso.

Estoy de acuerdo con que Daniel sugiere que tal vez la excepción se esté produciendo en un subproceso separado: intente conectar el evento de excepción de subproceso en la excepción Application.ThreadException. Esto se debe plantear cuando se produce cualquier excepción de hilo no manejado. Podrías adaptar tu código así: –

 using System.Threading; ... void Application_ThreadException(object sender, ThreadExceptionEventArgs e) { throw new ParserException(e.Exception.Message, e.Exception); } ... var exceptionHandler = new ThreadExceptionEventHandler(Application_ThreadException); Application.ThreadException += exceptionHandler; try { // Execution stopped at parser.prog() TimeDefParser.prog_return prog_ret = parser.prog(); return prog_ret == null ? null : prog_ret.value; } catch (Exception ex) { throw new ParserException(ex.Message, ex); } finally { Application.ThreadException -= exceptionHandler; } 

Te puedo decir lo que está pasando aquí …

Visual Studio se está rompiendo porque cree que la excepción no está controlada. ¿Qué significa no manipulado? Bueno, en Visual Studio, hay una configuración en Herramientas … Opciones … Depuración … General … “Habilitar solo mi código (solo administrado)”. Si se marca esta opción y si la excepción se propaga fuera de su código a un marco de stack asociado con una llamada de método que existe en un conjunto que no es “SU CÓDIGO” (por ejemplo, Antlr), se considera “no manejado”. Desactivo la función Habilitar solo mi código por este motivo. Pero, si me preguntas, esto es aburrido … digamos que haces esto:

 ExternalClassNotMyCode c = new ExternalClassNotMyCode(); try { c.doSomething( () => { throw new Exception(); } ); } catch ( Exception ex ) {} 

DoSomething llama a su función anónima allí y esa función lanza una excepción …

Tenga en cuenta que esta es una “excepción no controlada” de acuerdo con Visual Studio si “Habilitar solo mi código” está activado. Además, tenga en cuenta que se detiene como si fuera un punto de interrupción cuando estaba en modo de depuración, pero en un entorno de no depuración o producción, el código es perfectamente válido y funciona como se esperaba. Además, si simplemente “continuas” en el depurador, la aplicación continúa de manera alegre (no detiene el hilo). Se considera “no manejado” porque la excepción se propaga a través de un marco de stack que NO está en su código (es decir, en la biblioteca externa). Si me preguntas, esto es pésimo. Por favor, cambie este comportamiento predeterminado Microsoft. Este es un caso perfectamente válido de usar Excepciones para controlar la lógica del progtwig. A veces, no puede cambiar la biblioteca de terceros para que se comporte de otra manera, y esta es una manera muy útil de realizar muchas tareas.

Tome MyBatis, por ejemplo, puede usar esta técnica para detener el procesamiento de registros que se están recostackndo mediante una llamada a SqlMapper.QueryWithRowDelegate.

¿Estás utilizando .Net 1.0 o 1.1? Si es así, catch (Exception ex) no detectará excepciones de código no administrado. Deberás usar catch {} en su lugar. Vea este artículo para más detalles:

http://www.netfxharmonics.com/2005/10/net-20-trycatch-and-trycatchexception/

¿Es posible que la excepción sea lanzada en otro hilo? Obviamente, su código de llamada es de un solo hilo, pero tal vez la biblioteca que está consumiendo está realizando algunas operaciones multiproceso bajo la cubierta.

Estoy con @Shaun Austin: intente envolver el bash con el nombre completo

 catch (System.Exception) 

y ver si eso ayuda. ¿El documento de ANTLR dice qué excepciones deben lanzarse?

Personalmente no estoy convencido por la teoría de los hilos.

La única vez que vi esto antes, estaba trabajando con una biblioteca que también definía Excepción y los usos que había querido decir que el Catch real se refería a un tipo de “Excepción” diferente (si estaba completamente calificado, era Compañía). Lib.Exception, pero no fue por el uso, por lo que, cuando se trataba de detectar una excepción normal que estaba siendo lanzada (algún tipo de excepción de argumento, si recuerdo bien), simplemente no la detectaría porque el tipo no coincidía.

Entonces, en resumen, ¿hay otro tipo de Excepción en un espacio de nombres diferente que se usa en esa clase?

EDITAR: Una forma rápida de verificar esto es asegurarse de que en su cláusula catch usted califique completamente el tipo de Excepción como “System.Exception” y le dé un giro.

EDIT2: OK He intentado el código y concedo la derrota por ahora. Tendré que echarle otro vistazo por la mañana si nadie ha encontrado una solución.

Para mí, una cláusula catch (Exception) debería haber capturado cualquier excepción. ¿Hay alguna razón por la que no lo haría?

La única posibilidad que se me ocurre es que algo más lo atrapa y lo maneja de una manera que parece ser una excepción no detectada (por ejemplo, salir del proceso).

mi bloque try / catch no lo captura y, en cambio, detiene la ejecución como una excepción no controlada.

Necesitas encontrar qué está causando el proceso de salida. Podría ser algo más que una excepción no controlada. Puede intentar usar el depurador nativo con un punto de interrupción establecido en “{,, kernel32.dll} ExitProcess”. Luego use SOS para determinar qué código administrado está llamando al proceso de salida.

Hmm, no entiendo el problema. Descargué e intenté su ejemplo de archivo de solución.

Se lanza una excepción en TimeDefLexer.cs, línea 852, que posteriormente es manejada por el bloque catch en Program.cs que solo dice excepción manejada.

Si elimino el comentario del bloque catch que está sobre él, entrará en ese bloque.

Qué es lo que parece ser el problema aquí?

Como dijo Kibbee, Visual Studio se detendrá en las excepciones, pero si le pide que continúe, su código quedará atrapado en la excepción.

Descargué el proyecto VS2008 de muestra, y también estoy un poco perplejo aquí. Sin embargo, pude pasar por alto las excepciones, aunque probablemente no de una manera que funcione, será genial para ti. Pero aquí está lo que encontré:

Esta publicación de la lista de correo tuvo una discusión de lo que parece ser el mismo problema que estás experimentando.

Desde allí, agregué un par de clases ficticias en el archivo principal program.cs:

 class MyNoViableAltException : Exception { public MyNoViableAltException() { } public MyNoViableAltException(string grammarDecisionDescription, int decisionNumber, int stateNumber, Antlr.Runtime.IIntStream input) { } } class MyEarlyExitException : Exception { public MyEarlyExitException() { } public MyEarlyExitException(int decisionNumber, Antlr.Runtime.IIntStream input) { } } 

y luego agregó las líneas de uso en TimeDefParser.cs y TimeDefLexer.cs:

 using NoViableAltException = MyNoViableAltException; using EarlyExitException = NoViableAltException; 

Con eso, las excepciones se convertirían en las clases de excepciones falsas y podrían manejarse allí, pero todavía había una excepción lanzada en el método mTokens en TimeDefLexer.cs. Envolviendo eso en un try catch en esa clase atrapó la excepción:

  try { alt4 = dfa4.Predict(input); } catch { } 

Realmente no entiendo por qué envolverlo en el método interno en lugar de a dónde se llama desde el manejo del error si el subproceso no está en juego, pero espero que eso apunte a alguien más inteligente que yo aquí en la dirección correcta.

Descargué tu código y todo funciona como se esperaba.

El depurador de Visual Studio intercepta correctamente todas las excepciones. Los bloques de captura funcionan como se espera.

Estoy ejecutando Windows 2003 Server SP2, VS2008 Team Suite (9.0.30729.1 SP)

Intenté comstackr tu proyecto para .NET 2.0, 3.0 y 3.5

@Steve Steiner, las opciones de depuración que mencionó no tienen nada que ver con este comportamiento.

Intenté jugar con estas opciones sin efectos visibles: los bloques de captura lograron interceptar todas las excepciones.

Steve Steiner tiene razón en que la excepción se origina en la biblioteca antlr, pasa por el método mTokens () y queda atrapado en la biblioteca antlr. El problema es que este método es generado automáticamente por antlr. Por lo tanto, cualquier cambio para manejar la excepción en mTokens () se sobrescribirá cuando genere sus clases de analizador / lexer.

De forma predeterminada, antlr registrará errores e intentará recuperar el análisis. Puede anular esto para que parser.prog () lance una excepción cada vez que se encuentre un error. Desde su código de ejemplo, creo que este es el comportamiento que esperaban.

Agregue este código a su archivo grammer (.g). También deberá desactivar “Habilitar solo mi código” en el menú de depuración.

 @members { public override Object RecoverFromMismatchedSet(IIntStream input,RecognitionException e, BitSet follow) { throw e; } } @rulecatch { catch (RecognitionException e) { throw e; } } 

Este es mi bash de obtener una versión en C # del ejemplo dado en el capítulo “Cómo salir del reconocedor en el primer error” del libro “Referencia definitiva de ANTLR”.

Espero que esto es lo que estabas buscando.

Puede configurar VS.Net para que se interrumpa tan pronto como se produzca una excepción. Simplemente ejecute su proyecto en modo de depuración y se detendrá tan pronto como se lance la excepción. Entonces deberías tener una mejor idea de por qué no está siendo atrapado.

Además, puede ingresar algún código para capturar todas las excepciones no manejadas . Lea el enlace para obtener más información, pero los conceptos básicos son estas dos líneas.

 Application.ThreadException += new ThreadExceptionEventHandler(ThreadExceptionHandler); // Catch all unhandled exceptions in all threads. AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionHandler); 

Oh y en referencia a lo que dijo Kibbee; Si selecciona Depurar | Excepciones en VS y simplemente hace clic en todas las casillas en la columna ‘arrojado’, debería seleccionar todo AFAIK como una ‘primera excepción de oportunidad’, es decir, VS indicará cuándo la excepción está a punto de ser procesada por todo lo demás y romper en el código correspondiente. Esto debería ayudar con la depuración.

La mejor opción suena como configurar Visual Studio para interrumpir todas las excepciones no manejadas (Debug -> Exceptions dialog, marque la casilla “Common Language Runtime Exceptions” y posiblemente también las demás). Luego ejecuta tu progtwig en modo de depuración. Cuando el código del analizador ANTLR emite una excepción, debería ser capturado por Visual Studio y permitirle ver dónde está ocurriendo, el tipo de excepción, etc.

Según la descripción, el bloque catch parece correcto, por lo que podría estar sucediendo una de varias cosas:

  1. el analizador no está lanzando una excepción
  2. el analizador es, en última instancia, lanzar algo que no se deriva de System.Exception
  3. hay una excepción lanzada en otro hilo que no se está manejando

Parece que potencialmente ha descartado el problema # 3.

Hice un seguimiento a través del ensamblaje externo con Reflector y no encontré evidencia de roscas en absoluto.

No se puede encontrar ningún subproceso no significa que no hay subprocesos

.NET tiene un ‘grupo de subprocesos’, que es un conjunto de subprocesos ‘de repuesto’ que permanecen casi inactivos. Ciertos métodos hacen que las cosas se ejecuten en uno de los subprocesos del grupo de subprocesos para que no bloqueen su aplicación principal.

Los ejemplos flagrantes son cosas como ThreadPool.QueueUserWorkItem , pero hay muchas otras cosas que también pueden ejecutar cosas en el grupo de subprocesos que no parecen tan obvias, como Delegate.BeginInvoke

Realmente, necesitas hacer lo que sugiere el kibbee .

¿ha intentado imprimir (Console.WriteLine ()) la excepción dentro de la cláusula catch y no usar Visual Studio y ejecutar su aplicación en la consola?

Creo que Steve Steiner tiene razón. Al investigar las sugerencias de Steve, encontré este hilo hablando de la opción “Habilitar solo mi código” en Herramientas | Opciones | Depurador | General. Se sugiere que el depurador se interrumpirá en ciertas condiciones cuando el código que no sea de usuario lance o maneje una excepción. No estoy exactamente seguro de por qué esto importa, o por qué el depurador dice específicamente que la excepción no fue manejada cuando realmente lo fue.

Pude eliminar las falsas interrupciones al deshabilitar la opción “Habilitar solo mi código”. Esto también cambia el cuadro de diálogo Debug | Exceptions eliminando la columna “Manejo por el usuario” ya que ya no se aplica. O, simplemente puede desmarcar la casilla “Gestionado por el usuario” para CLR y obtener el mismo resultado.

Muchísimas gracias por la ayuda a todos!

“Además, puedes ingresar código para capturar todas las excepciones no manejadas. Lee el enlace para obtener más información, pero lo básico son estas dos líneas”.

Esto es falso Esto solía detectar todas las excepciones no controladas en .NET 1.0 / 1.1, pero era un error y se suponía que no, y se solucionó en .NET 2.0.

 AppDomain.CurrentDomain.UnhandledException 

Solo está diseñado para ser utilizado como un salón de registro de última oportunidad para que pueda registrar la excepción antes de que el progtwig salga. No detectará la excepción a partir de 2.0 (aunque en .NET 2.0 al menos hay un valor de configuración que puede modificar para que actúe como 1.1, pero no es una práctica recomendada usar esto).

Vale la pena señalar que hay algunas excepciones que no puede detectar, como StackOverflowException y OutOfMemoryException. De lo contrario, como otras personas han sugerido, podría ser una excepción en un hilo de fondo en algún lugar. También estoy bastante seguro de que tampoco puede detectar algunas / todas las excepciones no administradas / nativas.

No lo entiendo … su bloque catch solo lanza una nueva excepción (con el mismo mensaje). Lo que significa que su statement de:

El problema es que, en algunos casos (no todos), mi bloque try / catch no lo detectará y, en cambio, detendrá la ejecución como una excepción no controlada.

Es exactamente lo que se espera que suceda.

Estoy de acuerdo con Daniel Auger y kronoz en que esto huele como una excepción que tiene algo que ver con los hilos. Más allá de eso, aquí están mis otras preguntas:

  1. ¿Qué dice el mensaje de error completo? ¿Qué tipo de excepción es?
  2. Basado en el seguimiento de stack que ha proporcionado aquí, ¿no es la excepción lanzada por su código en TimeDefLexer.mTokens ()?

No estoy seguro de que no esté claro, pero si es así, veo que el depurador detiene la ejecución con una “Excepción no controlada” de tipo NoViableAltException. Inicialmente, no sabía nada acerca de este elemento del menú Depuración-> Excepciones porque MS espera que, en el momento de la instalación de VS, se comprometa con un perfil cuando no tenga idea de qué tan diferentes son. Aparentemente, no estaba en el perfil de C # dev y faltaba esta opción . Después de finalmente depurar todas las excepciones de CLR lanzadas, desafortunadamente no pude descubrir ningún nuevo comportamiento que conduzca a la razón de este problema de excepciones no manejadas. Todas las excepciones lanzadas fueron esperadas y supuestamente se manejaron en un bloque try / catch.

Revisé la asamblea externa y no hay evidencia de subprocesos múltiples. Con eso, quiero decir que no existe ninguna referencia a System.Threading y que no se utilizaron delegates en absoluto. Estoy familiarizado con eso constituye una instanciación de un hilo. Lo verifico observando la caja de herramientas de Subprocesos en el momento de la excepción no controlada para ver que solo hay un subproceso en ejecución.

Tengo un problema abierto con la gente de ANTLR, así que tal vez hayan podido abordar este problema antes. He podido replicarlo en un proyecto de aplicación de consola simple utilizando .NET 2.0 y 3.5 bajo VS 2008 y VS 2005.

Es solo un punto de dolor porque obliga a mi código a trabajar solo con entradas de analizador válidas conocidas. El uso de un método IsValid() sería arriesgado si lanzara una excepción no controlada basada en la entrada del usuario. Mantendré esta pregunta actualizada cuando se sepa más sobre este problema.

@spoulson,

Si puedes replicarlo, ¿puedes publicarlo en algún lugar? Una vía que podría probar es usar WinDBG con las extensiones SOS para ejecutar la aplicación y detectar la excepción no controlada. Se romperá en la primera excepción de oportunidad (antes de que el tiempo de ejecución intente encontrar un manejador) y podrá ver en ese punto de dónde viene y qué hilo.

Si no ha usado WinDBG anteriormente, puede ser un poco abrumador, pero aquí hay un buen tutorial:

http://blogs.msdn.com/johan/archive/2007/11/13/getting-started-with-windbg-part-i.aspx

Una vez que inicie WinDBG, puede alternar la ruptura de las excepciones no manejadas yendo a Depurar-> Filtros de eventos.

Wow, así que de los informes hasta el momento, 2 funcionaron correctamente y 1 experimentó el problema que informé. ¿Cuáles son las versiones de Windows, Visual Studio usado y .NET framework con números de comstackción?

Estoy ejecutando XP SP2, VS 2008 Team Suite (9.0.30729.1 SP), C # 2008 (91899-270-92311015-60837) y .NET 3.5 SP1.

Si está utilizando objetos COM en su proyecto y prueba que los bloques de captura no detectan las excepciones, tendrá que deshabilitar las Herramientas / Depuración / Interrupción cuando las excepciones crucen el dominio de aplicaciones o los límites administrados / nativos (solo administrados).