Как я могу запускать метод через определенные промежутки времени? System.Timers.Timer, кажется, теряет синхронизациюC#

Место общения программистов C#
Ответить
Anonymous
 Как я могу запускать метод через определенные промежутки времени? System.Timers.Timer, кажется, теряет синхронизацию

Сообщение Anonymous »

В моем текущем проекте я хочу отправить предопределенную тактильную информацию, синхронизированную с видео.
Например, на видео сильный ветер, и я хочу отправить ощущение.
Эти тактильные данные необходимо рассчитать.
Я хочу рассчитать и отправить данные с фиксированным интервалом в 0,1 секунды.
План состоит в том, чтобы отправить рассчитанные данные, а затем запустить расчет следующих данных.Для этого я использовал System.Timers.Timer с AutoReset = true и истекшим событием.
Условие, которого я пытаюсь достичь, выглядит следующим образом.
  • Данные не должны отправляться точно каждые 0,1 секунды.
  • Рассчитанные данные предназначены для момент в видео, поэтому внутренний таймер и таймер видео должны примерно синхронизироваться.
  • Если вычисление данных занимает больше 0,1 секунды, мы просто повторно отправьте последний рассчитанный пакет.
Однако я наткнулся на проблему с синхронизацией таймера. Вот журнал каждый раз, когда я отправляю Sensation с количеством тактов слева и фактически прошедшим временем (определяемым System.Diagnostics.Stopwatch) с номером тика слева и миллисекундами с момента начала выполнения справа.< /p>

Код: Выделить всё

1 / 106
2 / 216
3 / 326
4 / 448
5 / 554
6 / 660
7 / 768
8 / 875
9 / 983
10 / 1090
11 / 1213
12 / 1322
13 / 1431
14 / 1539
15 / 1647
16 / 1754
17 / 1861
18 / 1968
19 / 2075
20 / 2197
...
154 / 16885
155 / 16994
156 / 17100
157 / 17207
158 / 17317
159 / 17426
Обычно каждый такт в 0,1 секунды, при котором отправляются данные, выполняется чуть позже, чем 0,1 секунды (это нормально), и следующая задержка отправки складывается поверх этой задержки (что неправильно), поэтому после 15 секунд выполнения таймер отставал уже примерно на 2 секунды.
Похоже, что новый интервал начинается только после выполнение прошедших событий, а не немедленно.
Код у меня выглядел примерно так.

Код: Выделить всё

private int tick = 0;

private System.Timers.Timer timer;
private System.Diagnostics.Stopwatch watch;

private Constructor() {
timer = new System.Timers.Timer(100);
timer.Elapsed += streamSensation; // simply sends the Sensation (and created above logs)
timer.Elapsed += calcManagerTick; // mainly calculates the Sensation for next Tick
timer.AutoReset = true;
timer.Enabled = false;
}

private void streamSensation(Object source, ElapsedEventArgs e) {
// Send data
tick++;
Console.WriteLine(tick + " / " + watch.ElapsedMilliseconds);
}

private void calcManagerTick(Object source, ElapsedEventArgs e) {
// load and do stuff based on tick variable
}

private void start() {
if (!timer.Enabled) {
watch = Stopwatch.StartNew();
timer.Start();
}
}

Единственные решения, которые приходят мне на ум, — это какие-то хакерские решения, например, пересчет интервала в каждом цикле с помощью секундомера, чего я не хочу делать, потому что уверен, что есть лучшие решения.

Подробнее здесь: https://stackoverflow.com/questions/785 ... eems-to-lo
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»