verdad usuario try tipos tabla sirven que predefinidas practicas por para manejo las flop excepciones entradas elevar ejercicios definidas con catch buenas asincronas aplicaciones .net c++ exception-handling clr clr-hosting

.net - usuario - Manejo de excepciones de alojamiento de CLR en un hilo no creado por CLR



preset clear flip flop (1)

La actualización implica que quizás tenga una solución aquí. Sin embargo, su solución no funcionará en todos los casos, así que aquí hay más información.

Si prefiere el comportamiento de Excepción no controlada de CLR, entonces convierta ese programa en el más externo y llame al código nativo solo para realizar funciones específicas. Eso asegurará que el CLR obtenga el control del filtro de excepciones no manejado.

Si desea conservar su estructura actual y el código C ++ que tiene es pequeño, podría dejar de usar el CRT (lo que le negará un montón de cosas útiles, incluidos los constructores estáticos y el manejo de excepciones de C ++). Eso asegurará que el CLR obtenga el filtro de excepciones no manejadas.

Y, por supuesto, usted podría simplemente llamar a SetUnhandledExceptionFilter usted mismo y obtener el comportamiento que desea.

Sin embargo, creo que la mejor recomendación en esta situación es poner una función real con un bloque catch en la pila de llamadas de cualquier hilo en el que quiera hacer algo cuando ocurra una excepción y no confiar en el mecanismo UEF, porque en el contexto de un sistema de componentes, siempre es frágil ya que varios usuarios compiten por él.

Martyn

La cuestión:

Una excepción no controlada en un subproceso que ingresa al CLR desde un código no administrado no activa el procesamiento CLR de la excepción no manejada "normal".

En el código a continuación llamando a CSSimpleObject.GetstringLength() desde C ++ con

  • "1" lanza una excepción en el subproceso de llamada (subproceso no creado por CLR),
  • "2" lanza una excepción en un nuevo Thread () (thread creado por CLR).

En el caso de "1"

  • CurrentDomain_UnhandledException () nunca se llama.
  • El dominio de la aplicación y el proceso se mantendrán cargados y en ejecución, solo obtendrá un ERROR.

En el caso "2" (comportamiento esperado)

  • Se llama a CurrentDomain_UnhandledException ().
  • El proceso se mata.

La pregunta:

¿Qué hay que hacer para obtener el comportamiento "normal"?

Código de muestra:

El siguiente código se basa en el ejemplo de código " CppHostCLR " de Visual Studio 2010 de " CppHostCLR ejemplos de interoperabilidad y fusión ".

RuntimeHost (C ++):

PCWSTR pszStaticMethodName = L"GetStringLength"; PCWSTR pszStringArg = L"1"; //PCWSTR pszStringArg = L"2"; hr = pClrRuntimeHost->ExecuteInDefaultAppDomain(pszAssemblyPath, pszClassName, pszStaticMethodName, pszStringArg, &dwLengthRet); if (FAILED(hr)) { wprintf(L"Failed to call GetStringLength w/hr 0x%08lx/n", hr); goto Cleanup; }

Código gestionado (C #):

public class CSSimpleObject { public CSSimpleObject() { } //------8<---------- public static int GetStringLength(string str) { AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); switch (str) { case "1": throw new Exception("exception in non-CLR-created thread"); case "2": Thread thread = new Thread(new ThreadStart(WorkThreadFunction)); thread.Start(); break; } return str.Length; } static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { Console.WriteLine("CurrentDomain_UnhandledException:" + e.ToString()); Console.ReadKey(); } public static void WorkThreadFunction() { throw new Exception(""exception in CLR-created thread""); }

Investigación hasta ahora:

MSDN inicialmente implica que las excepciones no controladas en un subproceso no creado por CLR deberían comportarse más o menos "naturalmente"; consulte " Excepciones en subprocesos administrados "

El tiempo de ejecución de lenguaje común permite que la mayoría de las excepciones no manejadas en los hilos procedan de forma natural. En la mayoría de los casos, esto significa que la excepción no controlada hace que la aplicación finalice ".

"La mayoría" significa que en los subprocesos creados por CLR internos, las excepciones de aborto de subprocesos y descargadas de Application Domain se manejan de manera diferente. En hilos no-CLR

"proceden normalmente, resultando en la terminación de la solicitud".

Investigaciones adicionales me llevaron a " Procesamiento de excepciones no manejadas en el CLR " donde descubrí lo siguiente:

"si la excepción no se manejó ... en el método administrado, la excepción saldrá del CLR pero continuará propagándose en la pila como una excepción SEH nativa (las excepciones administradas se representan como excepciones SEH nativas) ... La excepción no controlada del sistema operativo "El mecanismo de filtro (UEF) no siempre activa el procesamiento de excepciones no manejadas de CLR. En circunstancias normales, esto funcionará como se espera y el procesamiento de excepciones no manejadas de CLR se activará. Sin embargo, en ciertos casos esto puede no suceder".

¿Qué está mal con el código anterior o cómo se puede cambiar para que se active el procesamiento de excepciones no manejadas de CLR?

Actualización (2011-05-31):

Acabo de encontrar un informe de error antiguo, "UnhandledExceptionEventHandler no se llama cuando el código administrado se llama desde no administrado y lanza una excepción - http://tinyurl.com/44j6gvu ", donde Microsoft confirma que este es un comportamiento "defectuoso":

Gracias por tomarse el tiempo para reportar este problema. El comportamiento es de hecho un error causado por el motor de ejecución CLR y el CRT que compite por el UnhandledExceptionFilter . La arquitectura del CLR se ha revisado en la versión 4.0 que admite este escenario.

Actualización (2011-06-06):

¿Por qué es importante hacer esto bien?

  • Si está creando un entorno de alojamiento, sus desarrolladores esperan un comportamiento consistente en el manejo de excepciones.
  • a menos que haya una manera de activar el "manejo de excepciones CLR normal" en un subproceso nativo, significa que siempre tiene que transferir la ejecución a un subproceso administrado (en cola en un grupo de subprocesos, por ejemplo)
  • todavía hay esa pequeña cantidad de ejecución de transferencia de código de un subproceso nativo a uno administrado ... que tiene que detectar todas las excepciones y de alguna manera manejar esa situación de manera diferente

Nota: cambiar el comportamiento de CLR a través de SetActionOnFailure() hace que las cosas empeoren, en el sentido de que termina ocultando la excepción original (es decir, en lugar de una memoria sin memoria, al final se ve un Aborto de subprocesos, sin una pista de dónde proviene el error original).