У меня есть приложение, которое использует счетчики производительности, которые работали в течение нескольких месяцев. Теперь, на моей машине dev и другой машине разработчика, она начала висит, когда я называю PerformanceCounterCategory.Exists. Насколько я могу судить, он висит бесконечно. Не имеет значения, какую категорию я использую в качестве входных данных, а другие приложения, использующие API, демонстрируют то же поведение.
Отладка (с использованием MS Symbol Servers) показала, что это вызов Microsoft.Win32.RegistryKey, который зависает. Дальнейшее исследование показывает, что именно эта линия висит:
while (Win32Native.ERROR_MORE_DATA == (r = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref sizeInput))) {
Это в основном цикл, который пытается выделить достаточно памяти для данных счетчика производительности. Он начинается с size = 65000
и выполняет несколько итераций. В 4-м вызове, когда size = 520000
, Win32Native.RegQueryValueEx
зависает.
Более того, скорее, я нашел этот комментарий в исходном источнике для 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.
Кто-нибудь видел это поведение раньше? Что я могу сделать, чтобы решить эту проблему?