Можно ли игнорировать вызов WaitHandle.SignalAndWait для профилирования производительности? - PullRequest
3 голосов
/ 23 июня 2009

Я только что скачал пробную версию ANTS Performance Profiler из Red Gate и изучаю код моей команды.Сразу же я замечаю, что есть определенная часть кода, о которой ANTS сообщает, что она потребляет до 99% процессорного времени.

Я совершенно незнаком с ANTS или профилированием производительности в целом (то есть, за исключением самопрофилирования с использованиемя уверен, что это очень грубые и недовольные методы, такие как double timeToComplete = (endTime - startTime).TotalSeconds), так что я все еще возлюсь с приложением и выясняю, как оно используется.Но я позвонил разработчику, ответственному за рассматриваемый код, и его немедленной реакцией было: «Да, меня не удивляет, что он так говорит; но этот код вызывает SignalAndWait [который я смог увидеть сам, благодаря ANTS], чтоне использует никакого процессора, он просто сидит и ждет, когда что-то сделает ".Он посоветовал мне просто игнорировать этот код и искать что-нибудь еще, что я смог найти.

Мой вопрос: правда ли, что SignalAndWait не требует НИКАКИХ затрат ЦП (и если да, то как это возможно?), И действительно ли это возможно?Разумно ли, что профилировщик производительности посчитает, что он занимает 99% процессорного времени?Я нахожу это особенно любопытным, потому что, если он равен 99%, это может означать, что наше приложение часто бездействует, не так ли?И все же его производительность в последнее время стала довольно вялой.

Как я уже сказал, я действительно новичок, когда дело доходит до этого инструмента, и я ничего не знаю о классе WaitHandle.Так что любая информация, которая поможет мне понять, что здесь происходит, будет оценена.

Ответы [ 2 ]

1 голос
/ 24 июня 2009

WaitHandle действительно усыпляет ваш поток.

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

Вы также можете сигнализировать WaitHandle из другого потока (например, выход из приложения и т. Д.), И они сразу WakeUp.

Лично я предпочитаю WaitHandle с коротким тайм-аутом по сравнению с Thread.Sleep с тем же тайм-аутом, что и при запуске Sleep, должен вернуться, прежде чем вы сможете возобновить работу, тогда как WaitHandle может быть немедленно возобновлен если требуется.

0 голосов
/ 24 июня 2009

Я думаю, у вас может быть серьезная ошибка в вашем коде. EventWaitHandle имеет 2 семантики в зависимости от режима сброса. Когда EventWaitHandle находится в режиме автоматического сброса, все ожидающие потоки блокируются до тех пор, пока событие не будет сигнализировано, после того как событие станет сигналом, последующие операции ожидания на нем сбрасывают его состояние и поток, вызывающий блок ожидания, снова на нем.

Однако, если EventWaitHandle находится в режиме ManualReset, он останется сигнальным до тех пор, пока вы не вызовете Reset Manually для него, это означает, что если EventWaitHandle сигнализируется и поток вызывает ожидание в нем в узком цикле, этот поток не будет блокировать до тех пор, пока не будет вызван сброс для события, поэтому рассмотрим этот гипотетический сценарий

EventWaitHandle h1, h2;
h1 = new EventWaitHandle(true, EventWaitHandle.ManualReset); // the event is already signaled.
h2 = new EventWaitHandle(false, EventWaitHandle.ManualReset);
while(true)
{
  WaitHandle.SignalAndWait(h2,h1);
}

вышеприведенный цикл съест большую часть вашего ЦП, пока какой-нибудь другой поток не вызовет h1.Reset (), что сделает блоки SignalAndWait.

Надеюсь, это поможет.

Для получения дополнительной информации, проверьте http://msdn.microsoft.com/en-us/library/system.threading.eventwaithandle.aspx

...