Более точная альтернатива Thread.Sleep(1) - C#

Узнай цену своей работы

Формулировка задачи:

Как подсказывает мне гугл, Thread.Sleep - это зло во плоти, атата, руки оторвут, и т.д. Раньше проблем не было, пока не возникла следующая задача: мультипотоковое приложение c бесконечными циклами с настраиваемыми задержками шагом 1 мс. Принципиальная схема говнокодерская и выглядит так:
Листинг программы
  1. // класс-наследник от BackgroundWorker, переопределяет метод:
  2. protected override void OnDoWork(DoWorkEventArgs e)
  3. {
  4. while (true)
  5. {
  6. if (delay > 0)
  7. {
  8. stopwatch.Start();
  9. while (stopwatch.Elapsed.Milliseconds < delay)
  10. {
  11. Thread.Sleep(1);
  12. }
  13. stopwatch.Reset();
  14. }
  15. // обработка некоих данных, поступающих извне
  16. Thread.Sleep(1); //ради того, чтобы отпустить CPU и не грузить его на 100%
  17. }
  18. }
Что было обнаружено:
But beware: Windows is not a real-time OS, so you will not get 1000 wakes per second from Thread.Sleep(1). If you haven't used timeBeginPeriod to set your minimum resolution you'll wake about every 15 ms.
И я вижу абсолютно такую же историю. Любая задержка от 1 до 15 включительно выглядит, как 15 мс. Разница начинает быть видна от 16 и далее. Кроме того, задержка самого потока тоже тормозит его работу на 15 мс в случае, если delay не равна нулю. Мне же нужно, чтобы поток реагировал с точностью в 1 мс, и чтобы дополнительную задержку можно было ставить с шагом 1 мс. Если вообще убрать sleep(1), всё работает безупречно. Скорость реакции потока на внешние раздражители, которые он и обрабатывает - десятая доля миллисекунды. Настройка доп.задержки - идеальная точность, плюс-минус десять тиков. НО. Поток грузит cpu. Вопрос - как добиться того, чтобы поток работал "почти" в реальном времени (с задержкой реакции 1 мс или меньше), дополнительная задержка работала с точностью 1 мс, но при этом поток не грузил CPU на 100% ?

Решение задачи: «Более точная альтернатива Thread.Sleep(1)»

textual
Листинг программы
  1. using System;
  2. using System.Threading;
  3. using System.Timers;
  4. using Timer = System.Timers.Timer;
  5.  
  6. namespace ConsoleApplication23
  7. {
  8.     class Program
  9.     {
  10.         private static int i = 0;
  11.         static void Main(string[] args)
  12.         {
  13.             var timer = new Timer(1);
  14.             timer.Elapsed += (_, __) =>
  15.                              {
  16.                                  if (i > 0)
  17.                                      Console.WriteLine(i);
  18.                              };
  19.             timer.Start();
  20.             Console.ReadKey();
  21.         }
  22.     }
  23. }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

5   голосов , оценка 4.2 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут