2010-11-17 8 views
34

Tengo una aplicación que usa contadores de rendimiento, que funcionó durante meses. Ahora, en mi máquina de desarrollo y otra máquina de desarrollo, comenzó a colgarse cuando llamé a PerformanceCounterCategory.Exists. Por lo que puedo ver, se cuelga indefinidamente. No importa qué categoría utilizo como entrada, y otras aplicaciones que usan la API exhiben el mismo comportamiento.¿Qué haría que PerformanceCounterCategory.Exists se cuelgue indefinidamente?

La depuración (utilizando los servidores de símbolos MS) ha demostrado que se trata de una llamada a Microsoft.Win32.RegistryKey que se cuelga. La posterior investigación muestra que es esta línea que cuelga:

while (Win32Native.ERROR_MORE_DATA == (r = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref sizeInput))) { 

Esto es, básicamente, un bucle que intenta asignar suficiente memoria para los datos del contador de rendimiento. Comienza en size = 65000 y hace algunas iteraciones. En la 4ª llamada, cuando se bloquea size = 520000, Win32Native.RegQueryValueEx.

Además, en lugar worringly, me encontré con este comentario en la fuente de referencia para PerformanceCounterLib.GetData:

// Win32 RegQueryValueEx for perf data could deadlock (for a Mutex) up to 2mins in some 
    // scenarios before they detect it and exit gracefully. In the mean time, ERROR_BUSY, 
    // ERROR_NOT_READY etc can be seen by other concurrent calls (which is the reason for the 
    // wait loop and switch case below). We want to wait most certainly more than a 2min window. 
    // The curent wait time of up to 10mins takes care of the known stress deadlock issues. In most 
    // cases we wouldn't wait for more than 2mins anyways but in worst cases how much ever time 
    // we wait may not be sufficient if the Win32 code keeps running into this deadlock again 
    // and again. A condition very rare but possible in theory. We would get back to the user 
    // in this case with InvalidOperationException after the wait time expires. 

Alguien ha visto este comportamiento antes? ¿Qué puedo hacer para resolver esto?

+2

Muy buena investigación, +1. Sí, adelante y preocúpate, toda la API de la taquilla de grabación tiene un defecto inmanejable. Un modelo demasiado simple que ya no se podía atornillar sobre la próxima versión de Windows. Vista hizo una gran pausa de eso. ¡Suerte con ello! –

Respuesta

24

Este problema ya está solucionado, y como no ha habido respuestas aquí, agregaré una respuesta aquí en caso de que la pregunta se encuentre en búsquedas futuras.

En última instancia, solucioné este error deteniendo el servicio de la cola de impresión (como medida temporal).

Parece que la lectura de los contadores de rendimiento realmente necesita enumerar las impresoras en el sistema (confirmado por un volcado de WinDbg de un proceso de ejecución, donde puedo ver en la pila que winspool está enumerando impresoras, y está atrapado en una llamada de red). Esto era lo que realmente estaba fallando en el sistema (y efectivamente, la ventana de "Dispositivos e impresoras" también se colgó). Me desconcierta que un problema de impresora/red pueda hacer que los contadores de rendimiento bajen. Uno podría pensar que existió algún tipo de falla incorporada para tal caso.

Lo que estoy adivinando, es que esto se debe a una mala impresora/controlador en la red. Todavía no he vuelto a habilitar la impresión en los sistemas afectados, ya que estamos buscando la mala impresora.

+1

¿Es posible que la lectura de los contadores de rendimiento * provoque * que se cuelgue la cola de impresión? ¿Firma una segunda solicitud de algún recurso que bloquea algo que la primera solicitud necesita para terminar, o algo así? Supongo que esto no cambia la causa real, un mal conductor, pero me pregunto si el problema no se mostrará a menos que lo provoques de la manera que has detallado anteriormente. –

+1

Esta respuesta nos ayudó a solucionar un problema relacionado [new PerformanceCounter()] (http://stackoverflow.com/questions/2868068). La eliminación de una impresora antigua evitó el bloqueo y al menos mostró un mensaje de error que estamos persiguiendo. – crokusek

+0

Tengo un problema similar de un complemento de Outlook. ¿Qué herramienta usaste para depurar? Actualmente tengo Process Monitor, pero tengo problemas para encontrar el punto muerto –

Cuestiones relacionadas