Сон (10) ничего не делает? - PullRequest
1 голос
/ 09 декабря 2011

У меня странная ситуация с моим веб-сервисом.

Это простой - он создает поток, который работает постоянно, выполняет некоторые проверки диска в фоновом режиме и для каждого выполняемого им File.Exists., он переходит в Sleep (10), поэтому он не потребляет ВСЕ ядра процессора.

Все работает хорошо, пока я не войду в систему из RDP.Когда я это сделаю, этот поток будет всплывать и потреблять столько, сколько сможет.

Здесь, посмотрите, посмотрите ...

У меня два ядра, и мое приложение на переднем плане используетоколо 18% CPU (что показано на NOW-метре).Слева - загрузка процессора, когда никто не вошел в систему.

Что происходит?И еще - что нужно сделать, чтобы должным образом регулировать поток в этих условиях?

enter image description here

Мой фрагмент кода, который вызывает проблему:

foreach (string fi in files)
{
    if (_shouldStop)
    {
        break;
    }
    lock (_workItems)
    {
        StatusString = string.Format("Examining file Dir={0}\nmask={1}\nfile={2}\nqueue={3}",
            root, mask, fi, _workItems.Count);
    }
    lock (_workItems)
    {
        if (!_workItems.Contains(fi))
        {
            if (!File.Exists(TargetForFile(fi + ".hash")))
            {
                StatusString = string.Format("Adding file Dir={0}\nmask={1}\nfile={2}\nqueue={3}",
                root, mask, fi, _workItems.Count);
                _workItems.Add(fi);
            }
        }
    }
    Thread.Sleep(10);
}

Небольшое обновление:

Даже Sleep(1000) НИЧЕГО не делает, когда код запускается как служба Windows, и никто не подключен к машине.Я официально объявляю это WTF.

Ответы [ 4 ]

5 голосов
/ 09 декабря 2011

Не спи.Вместо этого установите для приоритета потока значение IDLE.

Далее следует определить потребление процессора на процесс , чтобы вы не преследовали красную сельдь.Откройте Perfmom.exe и посмотрите на объект Process(*)\(*) (все экземпляры).Затем вы можете проверить % Processor Time и % User Time для каждого процесса и определить, кто использует 18% при закрытии RDP.

В качестве примечания, а не shuffling same directories over and over againпочему бы не использовать вместо этого механизм уведомлений об изменениях ?

3 голосов
/ 09 декабря 2011

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

Я полагаю, что когда вы вошли в систему, достаточно того, что ваш поток не будет перенесен немедленно, так что он действительно окажется неактивным более 10 миллисекунд (и я думаю, что читал Максимальное разрешение сна составляет 100 миль, кстати). Однако, когда вы не используете RDP, поток становится доступным для повторного планирования гораздо чаще, поэтому он загружает больше ресурсов ЦП.

Чтобы проверить, попробуйте увеличить продолжительность сна до 500 (0,5 с) или 1000 или около того, чтобы дать вам заметный период сна.

Еще одним тестом было бы сбросить другой поток в цикле бездействия и посмотреть, сработает ли ваш поток file.exists, когда вы заставляете процессор быть занятым.

2 голосов
/ 09 декабря 2011

получают такие скачки, когда я вхожу в RDP, и у меня не работает ваш код. Бритва Оккама предполагает, что ядро ​​использует RDP.

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

Наконец, если вы не сделали ничего такого, как повышение приоритета процесса от Normal, то оно все равно будет делить ядра с другими процессами. Это может быть немного плохо, если он попадает в тесную петлю, но даже в этом случае планировщик должен предотвращать причинение слишком большого вреда сам по себе. Тем более с более свежими версиями Windows и если у вас более одного ядра.

Редактировать: На самом деле, все это поцарапать. Зачем опрашивать в цикле самостоятельно, а не в ответ на событие FileSystemWatcher . Задайте один или несколько FileSystemWatcher s для просмотра интересующего каталога (ов), а затем выполните опрос на предмет конкретных изменений в существовании файла, которые вас интересуют в ответ на это. Меньше работы для кода, и он должен быть более отзывчивым.

0 голосов
/ 09 декабря 2011

Спасибо за все предоставленные ответы, но я постараюсь предоставить один из моих.

Мне не нужно менять архитектуру на этом этапе, и любые попытки использовать любое количество Sleep() потерпели неудачу. Я искал несколько других сайтов, кроме SO, и нашел один поток, в котором Джон Скит предлагает использовать Monitor для передачи сигналов.

Это вдохновило меня на попытку изменить Sleep на WaitOne из AutoResetEvent, который я буду использовать только в качестве альтернативы сну, который, как кажется, не работает в моих обстоятельствах.

Попробовал, и это сработало!

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