Получение прошедшего времени с помощью DispatchTimer с точностью до 1 миллисекунды

Я пытаюсь измерить прошедшее время в миллисекундах между событиями нажатия клавиш с помощью таймера отправки, но при объявлении таймера отправки с интервалом в 1 миллисекунду, а затем установлении события тика, он не срабатывает каждую 1 миллисекунду, а где-то 10- 100 миллисекунд (примерно). Как точно измерить время в миллисекундах, если это событие тика не срабатывает вовремя? Я делаю это в Silverlight, у которого, похоже, нет доступа к System.Timers. То же самое происходит и с System.Threading.Timer.

Вот основы кода:

public void StartTimer(object o, RoutedEventArgs sender)
{
    System.Windows.Threading.DispatcherTimer myDispatcherTimer = new  
    System.Windows.Threading.DispatcherTimer();
    myDispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 1); // 1 Milliseconds 
    myDispatcherTimer.Tick += new EventHandler(Each_Tick);
    myDispatcherTimer.Start();
}

// A variable to count with.
int i = 0;

public void Each_Tick(object o, EventArgs sender)
{
    i++;
}

public void keypress(object s, EventArgs args)
{
    label1.contents = i.ToString();
    i = 0;
}

Любые идеи?


person James Santiago    schedule 23.11.2010    source источник


Ответы (2)


Точность таймера System.Threading в Silverlight составляет примерно 20 мс. Обычно вам нужен мультимедийный таймер, если вам нужно лучшее разрешение, но вы не можете получить к нему доступ непосредственно в Silverlight. Тем не менее, с некоторыми значительными настройками и компромиссами, я читал, что можно получить таймер Silverlight с точностью ~ 3 мс. См. документы, указанные здесь:

http://blogs.msdn.com/b/nikola/archive/2009/08/19/exposed-5-methods-to-create-game-loop-what-is-the-best.aspx

Обратите внимание, что я сам не проверял все эти альтернативы, но их стоит изучить.

Другой альтернативой является недавно представленная System.Diagnostics. Секундомер. К сожалению, это только иногда таймер с высоким разрешением, в зависимости от оборудования, на котором вы работаете. И документы MS не указывают, как они определяют, действительно ли это высокое разрешение или нет, поэтому ваш единственный вариант — проверить свойство IsHighResolution.

person Ken Smith    schedule 23.11.2010
comment
Похоже, 3 мс — это лучшее, на что я могу надеяться, пока не найду альтернативу или не найду этот секундомер в сборе. - person James Santiago; 23.11.2010

Вместо этого запустите Секундомер и просто вычтите текущее истекшее время секундомера. миллисекунды от последних истекших миллисекунд (которые вам нужно сохранить в переменной) каждый раз, когда нажимается клавиша.

    private Stopwatch _stopwatch;
    private int _lastElapsedMs;

    public void StartTimer(object o, RoutedEventArgs sender)
    {
        _lastElapsedMs = 0;
        _stopwatch = Stopwatch.StartNew();
    }

    public void keypress(object s, EventArgs args)
    {
        int elapsedMs = (int)_stopwatch.ElapsedMilliseconds;
        int currentElapsed = (elapsedMs - _lastElapsedMs);

        _lastElapsedMs = elapsedMs;

        label1.contents = currentElapsed.ToString();
    }
person Tim Lloyd    schedule 23.11.2010
comment
Я проверю это. Но сначала мне нужно обновить мой проект с Silverlight 3 до 4. - person James Santiago; 23.11.2010
comment
Похоже, что он не поддерживается в веб-проекте Silverlight. Только приложения для телефона или xbox. - person James Santiago; 23.11.2010