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

Вот периодический таймер с некоторыми вещами, которые должны произойти. Итак, как вы можете видеть, каждую секунду (прошедшие миллисекунды% 1000 == 0) он будет делать что-то, если выполняются некоторые условия. Но также каждые 10 миллисекунд мне нужно что-то проверять.

Вроде многовато, и после запуска таймера на 2 минуты он уже отстает на 1 секунду. Думаю, я неправильно подхожу к этому. Мог / должен я каким-то образом поместить всю эту логику в функцию, которая просто запускает асинхронно, чтобы таймер мог просто продолжать работать.

Это не конец света, если дисплей таймера то и дело тянется на несколько миллисекунд, если он настигнет позже. Но теперь весь таймер просто тянет.

_timer = Timer.periodic(Duration(milliseconds: 10), (timer) {
  passedMilliseconds = passedMilliseconds + 10;

  // METRONOME BEEP AND BLINK
  if (passedMilliseconds % currentTimerSettingsObject.milliSecondDivider == 0) {
    _playMetronomeBeep();
    _startMetronomeBlink();
  }

  // ONE SECOND
  if (passedMilliseconds % 1000 == 0) {
    secondsDuration--;

    // COUNTDOWN
    if (secondsDuration < currentTimerSettingsObject.countDown + 1) {
      _player.play('sounds/beep.mp3');
    }

    // SET COUNTDOWN START VALUES
    if (secondsDuration == currentTimerSettingsObject.countDown) {
      isCountdown = true;
    }
    notifyListeners();
  }

  // TIME IS UP
  if (secondsDuration < 0) {
    switchToNextTimer();
    notifyListeners();
  }
});

}

0
Christoffer 21 Фев 2021 в 23:48

1 ответ

Лучший ответ

Вы не можете полагаться на таймер, чтобы доставить события точно в срок. Вам нужно использовать более точный метод, чем простое увеличение счетчика на 10 на каждом тике. Одним из примеров может быть запуск Stopwatch перед таймером, а затем (зная, что ваши тики будут только с интервалами примерно 10 мс) прочитать stopwatch.elapsedMilliseconds и основывать свои решения на этом.

Вам нужно будет немного изменить свою логику. Например, вы хотите знать, когда вы пересекаете границу в 1 секунду. Раньше, с вашим точным шагом 10, вы знали, что в конечном итоге достигнете раунда 1000. Теперь вы можете увидеть 995, за которым следует 1006, и вам нужно сделать вывод, что вы пересекли вторую границу, чтобы запустить свою посекундную логику.

2
Richard Heap 21 Фев 2021 в 21:45