2012-01-12 20 views
10

Estoy investigando algunos bloqueos en mi aplicación causados ​​por una excepción de Win32, y he reducido que debe estar ocurriendo en el threadpool que se está ocupando del controlador de eventos EventLog.EntryWrittenEventHandler en mi solicitud. Lo configuran como esto:C# excepción de captura que está ocurriendo en ThreadPool

// Create the event log monitor 
eventLog.Log = "Application"; 
eventLog.EnableRaisingEvents = true; 
eventLog.EntryWritten += new EntryWrittenEventHandler(EventLogMonitor); 

EventLogMonitor es el controlador para mi evento. Me pregunto si alguien tiene alguna idea sobre dónde podría averiguar cuál es la causa de esta excepción. Parece que para escuchar eventos se está configurando un ThreadPoolWaitOrTimerCallback, que no tendría ninguno de mis códigos, y si ocurre la excepción en esto, simplemente no puedo ver cómo tratar este problema. ¡¡Cualquier ayuda es muy apreciada!!

Aquí está la salida de clrstack en WinDBG:

0:008> !clrstack 
OS Thread Id: 0x106c (8) 
ESP  EIP  
049df1c8 7756f871 [HelperMethodFrame: 049df1c8] 
049df26c 73ce6fa0 System.Diagnostics.EventLog.get_OldestEntryNumber() 
049df27c 73bf24ed System.Diagnostics.EventLog.CompletionCallback(System.Object) 
049df2c4 73bf0fe4 System.Diagnostics.EventLog.StaticCompletionCallback(System.Object, Boolean) 
049df2f4 744fc3b8 System.Threading._ThreadPoolWaitOrTimerCallback.WaitOrTimerCallback_Context(System.Object, Boolean) 
049df300 744fc373 System.Threading._ThreadPoolWaitOrTimerCallback.WaitOrTimerCallback_Context_f(System.Object) 
049df304 7400027f System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object) 
049df31c 744fc477 System.Threading._ThreadPoolWaitOrTimerCallback.PerformWaitOrTimerCallback(System.Object, Boolean) 
049df4ac 74991b5c [GCFrame: 049df4ac] 

En caso de que ayuda, mi solicitud es simplemente comprobando el ID de evento de cada entrada escrita en el registro de eventos, y si coincide con uno de una cierto conjunto de ID luego lo registro. Los bloqueos suceden silenciosamente rara vez, y la excepción es una excepción System.ComponentModel.Win32 con el mensaje 'Acceso denegado'. Parece que podría tratarse de un problema de permisos, pero ¿por qué funcionaría bien durante un cierto período y luego se interrumpiría repentinamente con esto?

+0

¿Qué tipo de excepción es? –

+0

Excepción System.ComponentModel.Win32 con el mensaje 'Acceso denegado'. Lo extraño es que ocurre muy raramente, mi aplicación que se ejecuta como un servicio puede durar días y de repente se cuelga con esto .. – DukeOfMarmalade

+0

¿Es posible que intente crear su propia fuente de eventos, nunca antes utilizada, y que se bloquea solo entonces? –

Respuesta

5

Si lo entiendo correctamente (sería útil si aprueba el stacktrace que lo lleva a la conclusión de que la excepción se produce dentro de un hilo de subprocesamiento), simplemente ajuste su código de EventLogMonitor en un bloque try/catch.

Ejemplo:

void EventLogHandler(object sender, EventArgs args) 
{ 
    try 
    { 
     // Your original code. 
    } 
    catch (Exception ex) 
    { 
     // Log or Write "ex" to the console. Set a breakpoint, whatever. 

     throw; 
    } 
} 

ACTUALIZACIÓN: después de su actualización, parece como si la excepción es, en efecto, no planteó desde el interior de su controlador, pero antes de que incluso se llama dentro de la clase EventLog.

Puede intentar registrar un controlador con el evento AppDomain.UnhandledException y realizar su registro/manejo allí. Tenga en cuenta que esto no le permitirá suprimir, "cambiar" o ajustar la excepción, sino simplemente registrarla en algún lugar con fines de diagnóstico.

Si solo desea inspeccionar la excepción una vez (o en ocasiones), intente utilizar el comando !PrintException de la extensión SOS en WinDBG.

ACTUALIZACIÓN 2: después de una investigación más profunda me resulta bastante extraño que la excepción salte a todos. Su stacktrace sugiere que está usando .NET 3.5 (o anterior, pero no 4.) y mirando la clase EventLog en Reflector puede ver que todo el manejo del EventWrittenHandler, incluido el código de preámbulo que parece causar la excepción, es envuelto en un gran bloque "try/catch (Exception)/catch". Gracioso.

+0

He agregado la salida de! Clrstack a mi pregunta. De hecho, he intentado con lo que sugieres Christian.K y mi aplicación aún se colgó sin disparar el try/catch. La excepción está ocurriendo en algunos Threadpool que .NET debe configurar para escuchar la entrada de eventos escritos del registro de eventos, y las excepciones no se propagan a través de hilos, así que no creo que esto funcione. ¡Gracias por la sugerencia! – DukeOfMarmalade

+0

Gracias por su ayuda en este tema Christian.K, todavía no he llegado al fondo de esto, tuve que pasar el problema a Microsoft, aunque sus sugerencias ayudaron mucho a investigar el problema. – DukeOfMarmalade

+0

Lástima que no pudimos resolver esto por completo. He vuelto a visitar el tema, casualmente, un par de veces, pero no se me ocurrieron nuevas ideas (lo que en realidad no dice mucho :-). –

0
  1. Si puede, use Tareas en System.Threading.Tasks.
  2. Intente, donde la acción está realizando lo que desea.

    ThreadPool.QueueUserWorkItem(state => 
    { 
        try 
        { 
         action(); 
        } 
        catch (Exception ex) 
        { 
         OnException(ex); 
        } 
    }); 
    
+0

No creo que esto funcione, cuando se suscribe al controlador de eventos EventLogEntryWritten parece que se ha iniciado un ThreadPool independiente para supervisar las entradas escritas en el registro de eventos, es en este ThreadPool donde se produce la excepción. – DukeOfMarmalade

1

Suscribirse a Application.ThreadException en sus Program.cs de la siguiente manera para poder detectar las excepciones que no están en el hilo principal.

static void Main() 
    { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.ThreadException += Application_ThreadException; 
     try 
     { 
      Application.Run(new MainForm()); 
     } 
     catch (Exception e) 
     { 
      HandleException(e); 
     } 
    } 

    static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) 
    { 
     HandleException(e.Exception); 
    } 
+2

+1 para ThreadException! –

0

No está seguro de qué tipo de aplicación se trata, por lo que en un caso general, si usted está teniendo ninguna suerte, intente enganchar en el dominio de aplicación en el que se ejecuta el código. Si no tiene varios dominios, puede intentar:

AppDomain.CurrentDomain.FirstChanceException += Handler

o

AppDomain.CurrentDomain.UnhandledException += Handler

Cuestiones relacionadas