Нужно, чтобы события выполнялись для событий таймера, метроном точности - PullRequest
1 голос
/ 17 марта 2010

Я установил таймер для вызова события в моем приложении. Проблема в том, что выполнение события перекошено другими операциями Windows. Ex. открытие и окно, загрузка веб-страницы. Мне нужно, чтобы событие оправдывалось точно вовремя, каждый раз.

Когда я впервые настроил приложение, использовал звуковой файл, например метроном, для прослушивания равномерного включения, в устойчивом состоянии, когда оно включено, но как только что-то происходит в среде Windows, звук срабатывает медленнее затем немного сбавил скорость, чтобы наверстать упущенное.

Итак, я добавил метод регистрации событий, чтобы сделать отметки таймера. Из этих данных видно, что приложение windows не влияет на таймер, но это влияет на вызовы событий моего приложения. Я понял это, проверив datetime.now в событии, и если я установил его на 250 миллисекунд, то есть 4 клика в секунду. Вы получаете данные примерно как ниже.

(сек) :( мс)

1: 000 1: 250 1: 500 1: 750

2: 000 2: 250 2: 500 2: 750

3: 000 3: 250 3: 500 3: 750

(допустим, я выполнил какое-то событие Windows) (время будет искажено)

4: 122 4: 388 4: 600 4: 876

(прекратить делать то, что я делал в Windows) (собираюсь сократить данные для упрощения, мой список был длиной 30 секунд)

5: 124 5: 268 5: 500 5: 750

(вы бы вернули время на те же миллисекунды, что и в начале)

6: 000 6: 250 6: 500 6: 750

7: 000 7: 250 7: 500 7: 750

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

Есть ли что-нибудь, что я могу сделать в .NET, надеясь использовать приложение XAML / WPF, это исправит перекос событий?

ТНХ.

Ответы [ 2 ]

2 голосов
/ 17 марта 2010

Делать это право может быть очень, очень сложно, если вообще возможно. Определенные приложения для обработки аудио действительно трудно это сделать. Стандартные настройки компьютера не совсем сделаны для такого рода операций в реальном времени, потому что вы не можете контролировать, сколько потоков / процессов будет выполняться в фоновом режиме.

Однако, как первая попытка , вы можете использовать цикл вместо асинхронного триггера. Обратите внимание, что это может сильно увеличить нагрузку на процессор и все еще не гарантирует точную синхронизацию. Псевдо-код:

forever
{
     // This will bring your precision down to the level of thread 
     // timing precision
     Sleep(0); 

     LastTime = GetPerformanceTimer();
     if(LastTime > NextInterval)
     {
         // Play sound, update last time
     }
}

где GetPerformanceTimer - это какой-то метод, основанный на QueryPerformanceCounter. Однажды я написал очень простой профилировщик http://www.emphess.net/2009/03/04/a-very-simple-profiler/,, но код там очень прост и в основном дает время в секундах, так как таймер запускается с очень высокой точностью.

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

1 голос
/ 17 марта 2010

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

Похоже, вы хотите, чтобы события происходили в потоке пользовательского интерфейса точно в срок, и это будет проблемой. Код, который обновляет пользовательский интерфейс, должен выполняться в потоке пользовательского интерфейса. Если что-то еще происходит в потоке пользовательского интерфейса при срабатывании таймера, операция обновления от таймера должна ждать.

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

Если вам не нужно обновлять пользовательский интерфейс, вы можете получить несколько более согласованный ответ, используя System.Threading.Timer с методом обратного вызова, а не одним из таймеров, использующих события. Тем не менее, я был бы очень удивлен, если бы вы могли заставить любой метод на основе таймера надежно работать в этом приложении.

...