Простые галочки DispatchTimer ошибочны c WPF только в Win10 - PullRequest
0 голосов
/ 07 апреля 2020

Я пробовал это на Win7 и Win10. На Win7 работает как я думал, тик вызывается каждые 100мс. Но на win10 тик вызывается 2 раза при запуске, а затем останавливается, пока я не наведу указатель мыши на приложение, которое запускает тик в течение 1 раза. Это странно.

Я использую System. Windows .Threading.

Код полностью в коде для его проверки, и это все для простоты:

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            TimerGeneral(true);
        }

        public DispatcherTimer timer = new DispatcherTimer();
        int s;

        public void TimerGeneral(bool estado)
        {
            timer.Interval = TimeSpan.FromMilliseconds(100);

            if (estado && !timer.IsEnabled) { timer.Tick += timer_Tick; timer.Start(); }

            else if (!estado && timer.IsEnabled) { timer.Stop(); }

        }

        public void timer_Tick(object sender, EventArgs e)
        {
            Debug.WriteLine("tick" + s++);
        }
    }

Я немного растерялся, почему Win10 работает иначе, извините.

1 Ответ

0 голосов
/ 08 апреля 2020

Имейте в виду, что при создании экземпляра DispatcherTimer с использованием конструктора по умолчанию (как вы это сделали) таймер Dispatcher будет по умолчанию выполняться с DispatcherPriority.Background! Отсюда высокая задержка.

Укажите более высокий приоритет с помощью соответствующего конструктора:

var dispatcherTimer = new DispatcherTimer(DispatcherPriority.Normal, Application.Current.Dispatcher) 

Это должно решить вашу проблему.
Если задержка все еще слишком велика, попробуйте DispatcherPriority.Send (используйте с care).
Если операция отправлена ​​на Dispatcher в DispatcherPriority.Send, операция обходит очередь и сразу же выполняется.

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

В качестве альтернативы, если Timers.Timer или любой другой таймер работает лучше для вас, тогда просто используйте его. Вы можете выполнить соответствующий код пользовательского интерфейса, используя Application.Current.Dispatcher.Invoke(Action) или Application.Current.Dispatcher.InvokeAsync(Action).

...