DispatcherTimer замедляется при обновлении пользовательского интерфейса каждую минуту - PullRequest
1 голос
/ 20 декабря 2011

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

Следующий код замедляется на каждую минуту на «1 секунду», что не очень хорошо при расчете счета. Подскажите, пожалуйста, где я не прав?

System.Windows.Threading.DispatcherTimer dispatcherTimer; 
int seconds = 0;
public string Counter { get; set; }
public Timer()
    {
        InitializeComponent();
        this.DataContext = this;
        dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
        dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
        dispatcherTimer.Interval = new TimeSpan(0, 0, 1);         
    }
  private void dispatcherTimer_Tick(object sender, EventArgs e)
    {

       Counter = (seconds / 3600).ToString() + ":" + (seconds / 60).ToString("00") + ":" + (seconds % 60).ToString("00");
       NotifyPropertyChanged("Counter");
       seconds++;
    }

Я сравнил этот таймер с другими секундомерами как в Интернете, так и в мобильном телефоне, этот таймер задерживается на секунду на каждую минуту.

Ответы [ 2 ]

4 голосов
/ 20 декабря 2011

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

Почему бы вам не взять момент времени и не сохранить его,

private DateTime startTime;

public Timer()
{
    InitializeComponent();
    startTime = DateTime.Now;
}

private void dispatcherTimer_Tick(object sender, EventArgs e)
{
    Counter = (DateTime.Now - startTime).ToString();
    ...
}

Фактически, взяв код, подобный этому, вы узнаете, почему у вас возникли проблемы.Метод ToString показывает счетчик более точно, включая миллисекунды, и выясняется, что таймер срабатывает не каждую 1 секунду, а скорее как каждые 1,01 секунды.

Я получаю такие значения, как

1.008
1.02
1.031
1.03901

и т. Д.

Затем вы можете заменить вышеприведенное на следующее:

private void dispatcherTimer_Tick(object sender, EventArgs e)
    {
        TimeSpan elapsedTime = (DateTime.Now - startTime);
        Counter = string.Format("{0:hh\\:mm\\:ss}", elapsedTime);

И оно будет отформатировано так, как раньше, без миллисекунд.

1 голос
/ 20 декабря 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...