Интервал таймера увеличивается при увеличении загрузки процессора и памяти

#c# #multithreading #timer #cpu

#c# #многопоточность #таймер #процессор

Вопрос:

В моем коде есть таймер на несколько ‘x’ секунд. Код имеет несколько потоков и несколько таймеров. Теперь я замечаю, что мое приложение переходит в состояние зависания после запуска в течение некоторого времени, и из журналов я замечаю, что интервал таймера меняется. Он увеличился. Как это возможно и кто-нибудь может предоставить решение для этого? Есть ли какая-либо альтернатива таймеру в c#

       _timernew = new System.Timers.Timer(10000)
            {
                AutoReset = false
            };
            _timernew .Elapsed  = (sender, e) => { DoSomething };
            _timernew .Enabled = true;
  

Комментарии:

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

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

3. Представьте, что вам нужно выполнять важную работу каждые 5 секунд, что займет 1 секунду. Простота управления. Теперь вам нужно выполнить 6 из этих важных заданий -> легко справиться вовремя?

4. В C # существует как минимум 5 классов таймеров. Какой из них вы используете?

5. В вашем вопросе все еще слишком мало деталей. Уменьшите масштаб и сообщите нам, для чего предназначен таймер.

Ответ №1:

Таймеры не являются точными. Интервал — это минимальная задержка перед запуском события, но вы не гарантируете, что ваше событие timer будет выполнено точно по истечении этого интервала.

По истечении этого интервала таймер помещает ваш обработчик even в очередь пула потоков. Следовательно, обработчик события будет выполнен, когда в пуле потоков есть доступный поток, который примет обработчик, а затем доступное ядро процессора, чтобы фактически выполнить его.

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

Если вам нужно выполнение ближе к реальному времени, вы должны использовать выделенный поток и установить его приоритет на высокий:

 Thread myThread = new Thread(MyThreadMethod);
myThread.Priority = ThreadPriority.Highest;
myThread.Start();
  

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

Вы не должны просто выполнять цикл и проверять время, потому что это займет одно ядро на 100%. Возможно, вы можете использовать страшный Thread.Sleep с меньшим интервалом и проверить, прошло ли время. Вы должны использовать меньший интервал, чем тот, который вам нужен, с величиной не менее 10. Thread.Sleep также не является точным.