проблема с секундомером .NET system.diagnostics

Я пытаюсь создать приложение, в котором используется класс секундомера.

Stopwatch sw = new Stopwatch();
sw.Start();
while (play)
{
    long timer = sw.ElapsedMilliseconds;
    Debug.WriteLine(timer);
}

Когда я протестировал этот цикл и проверил прошедшее время, я обнаружил, что программе не хватает нескольких миллисекунд.

некоторые часы из вывода отладчика:

31
32
33
34
35
36
37
38
40 ‹------39 пропущено
41
42
43

Любые предложения о том, как я могу решить эту проблему?


person RyanB    schedule 30.01.2011    source источник
comment
Как вы делаете вывод, что это коротко несколько мс?   -  person Marc Gravell    schedule 31.01.2011
comment
Я думаю, что вам, вероятно, потребуется предоставить более подробную информацию о том, что означают пропущенные миллисекунды - возможно, какой-то вывод.   -  person Neil    schedule 31.01.2011
comment
когда я проверил таймер в отладчике, выведите числа, где не последовательный пример 1,2,3, затем он переходит к 5.   -  person RyanB    schedule 31.01.2011
comment
Да ладно? иногда для обхода вашего цикла требуется более миллисекунды - (это кажется слишком длинным для простого, как ваш цикл). Вы не должны ожидать какой-либо согласованности от вызова к вызову в отношении того, сколько времени должна занять любая операция. Другие дела идут. Если вам нужно оптимизировать свое приложение, установите профилировщик, если нет, то перестаньте об этом беспокоиться. ЦП не устанет от выполнения ненужного кода.   -  person Neil    schedule 31.01.2011
comment
Этот вопрос ставится на очень многих уровнях: D   -  person Alastair Pitts    schedule 31.01.2011
comment
Нил, если бы я запускал целое приложение, скажем, со 100 или более строками кода, я бы не публиковал здесь, потому что я понимал, что это может быть проблемой производительности. однако я выполняю только код, показанный в сообщении   -  person RyanB    schedule 31.01.2011
comment
почему вам нужно, чтобы ваш цикл имел постоянное время работы? Вы сказали, что вам нужна точность до 10 мс, но почему?   -  person jb.    schedule 31.01.2011
comment
Что вы хотите решить? Что именно вы хотите сделать? В ядре Windows было и всегда будет (если они что-то кардинально не изменят) разрешение переключения задач 10 мс. Ваш процессор ушел, чтобы сделать что-то более важное для этой мс.   -  person Daniel Mošmondor    schedule 31.01.2011
comment
ну, я пытаюсь сделать приложение для запуска, которое в заранее определенные моменты времени (сигналы) выдает импульс через RS-232 и связывается с моим модулем запуска ... с 10 мс это было бы хорошо, но когда я добавил некоторые дополнительные функции, неточность была худшей.   -  person RyanB    schedule 31.01.2011
comment
Тот факт, что другие строки появляются через 1 мс, является чистым совпадением. Console.WriteLine() не является надежным инструментом синхронизации.   -  person Henk Holterman    schedule 31.01.2011
comment
Это было подробно рассмотрено ранее: таймер интервала разрешения"> stackoverflow.com/questions/4212611/   -  person Cody Gray    schedule 31.01.2011
comment
может кто подскажет подходящее решение? даже если это означает использование другого языка программирования   -  person RyanB    schedule 31.01.2011


Ответы (3)


Миллисекунды, которые вы теряете, связаны с тем, что ваша программа не единственная, работающая в ОС.

Итак, время от времени другие программы получают свой квант времени, и несколько миллисекунд не учитываются.

Вы не можете "исправить" это.

person Yochai Timmer    schedule 30.01.2011

Не хватает миллисекунд? Вы ожидаете увидеть запись для каждого миллисекундного тика в секунду? Например. 1000 в секунду? Если так, то этого никогда не произойдет. Не существует API синхронизации с точностью до 1 миллисекунды.

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

person Paul Sasik    schedule 30.01.2011
comment
Отличным примером неточности синхронизации является выполнение в Silverlight, где точность составляет всего 15 мс. - person Ray Booysen; 31.01.2011
comment
в моем приложении мне нужно, чтобы он был как минимум с точностью до 10 мс, однако, когда я увеличил количество строк кода и добавил некоторые функции, таймер пропустил чаще и до 60 мс: S - person RyanB; 31.01.2011
comment
Павел, я понимаю вашу точку зрения, я даже пытался увеличить приоритет приложения до реального времени и запустить исполняемый файл, а затем по завершении я передал результаты в файл, однако все еще были некоторые ошибки. реальная проблема заключается в том, что когда я добавляю некоторые базовые функции, такие как проверка того, что таймер находится в пределах определенного установленного времени, остается больше миллисекунд. - person RyanB; 31.01.2011
comment
Windows не является операционной системой реального времени. - person Lasse V. Karlsen; 31.01.2011
comment
Как сказал Лассе, Windows и C# не работают в режиме реального времени, поэтому вы не можете ожидать такой точности. Даже с такой точностью, как долго будет выполняться ваш код на каждом такте 10 мс? - person Ray Booysen; 31.01.2011

Debug.WriteLine может быть медленнее, чем 1 миллисекунда. Он не оптимизирован для скорости.

Вы можете добавить вызов, поместив сообщение в список, а затем записать список в Debug.WriteLine после запуска. Вы можете добавить фоновую задачу, отправляющую сообщение в Debug.WriteLine.

Оба должны препятствовать тому, чтобы таймер пропускал тики.

Другой причиной отсутствия галочек может быть ОС или другая программа, выполняющая какую-то работу между двумя вызовами Debug.WriteLine. Это может быть даже медленная машина.

Установка приоритета потока или запуск этого приложения на выделенном компьютере должны помочь, но такие проблемы с таймером ожидаются в Windows, поскольку никогда не говорилось, что это ОС реального времени.

person CodingBarfield    schedule 05.06.2013