Что заставит PerformanceCounterCategory.Exists зависать бесконечно? - PullRequest
39 голосов
/ 18 ноября 2010

У меня есть приложение, использующее счетчики производительности, которое работает месяцами.Теперь, на моем компьютере разработчика и другом компьютере разработчика, он начал зависать, когда я вызываю 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.

Есть кто-нибудьвидел это поведение раньше?Что я могу сделать, чтобы решить эту проблему?

1 Ответ

29 голосов
/ 21 ноября 2010

Эта проблема теперь исправлена, и, поскольку здесь не было ответов, я добавлю ответ здесь, если вопрос будет найден в будущих поисках.

Я в конечном итоге исправил эту ошибку, остановив службу диспетчера очереди печати (в качестве временной меры).

Похоже, что для чтения счетчиков производительности действительно необходимо перечислить принтеры в системе (что подтверждается дампом WinDbg процесса зависания, где в трассировке стека видно, что winspool перечисляет принтеры и застрял в сетевой вызов). Это было то, что на самом деле происходило с ошибкой в ​​системе (и, конечно же, открывалось окно «Устройства и принтеры»). Меня сбивает с толку, что проблема с принтером / сетью может привести к снижению счетчиков производительности. Можно подумать, что для такого случая был встроен какой-то отказоустойчивый.

Я предполагаю, что это вызвано плохим принтером / драйвером в сети. Я еще не включил печать на зараженных системах, так как мы ищем неисправный принтер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...