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?
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! –