Диспетчерский таймер замораживает WPF

Я разрабатываю приложение управления с 3 степенями свободы для AR Drone (четырехроторный БПЛА). Я использую несколько ПИД-контроллеров для управления БПЛА. Эти контроллеры реализованы с использованием класса диспетчерского таймера. Например, в начале программы. Я инициализирую таймер диспетчера, например:

        timer_yaw = new DispatcherTimer();
        timer_yaw.Interval = new TimeSpan(0, 0, 0, 0, 45);
        timer_yaw.Tick += new EventHandler(timer_yaw_tick);

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

        timer_yaw.Start();

в timer_yaw_tick я немного обрабатываю:

    private void timer_yaw_tick(object sender, EventArgs e)
      {
            // drone commands and stuff ... basically a PD controller
            DroneData data = droneControl.NavigationData;
            PV_yaw = data.Psi;

            SP_yaw = angle;

            Error_yaw = SP_yaw - PV_yaw;

            if (Error_yaw >= 0)
                yaw_pd = 0.5f;
            else if (Error_yaw < 0)
                yaw_pd = -0.5f;


            Derivative_yaw = (Error_yaw - PreError_yaw) / Dt_yaw;

            Output_yaw = (Kp_yaw * Error_yaw) + (Kd_yaw * Derivative_yaw);

            PreError_yaw = Error_yaw;

            Output_yaw = Math.Round(Output_yaw, 1, MidpointRounding.AwayFromZero);

            Output_yaw = Output_yaw * 1000;

            t_PD_yaw = Convert.ToInt32(Output_yaw);

            // this t_PD_yaw is then sent to the drone via WiFi to make required adjustment

        }

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

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

Помощь будет очень признательна .. Thnx


person Umer Qureshi    schedule 06.08.2012    source источник
comment
где в коде отладчик останавливается при зависании? (попробуйте несколько раз) Может ли быть проблема с одновременным доступом к данным? Код, который вы показываете, кажется для доступа к данным только для чтения, но может быть в какой-то другой части. У вас есть довольно много типов данных, которые существуют во фреймворке, которые являются потокобезопасными, проверьте их (msdn.microsoft.com/en-us/library/dd997305.aspx) Или используйте Mutex для самостоятельной обработки параллельного доступа. Но сначала просто попробуйте другой таймер, например System.Threading.Timer, это просто :-)   -  person GameAlchemist    schedule 06.08.2012


Ответы (1)


Скорее всего, вы используете Dispatcher по умолчанию, который связан с основным потоком пользовательского интерфейса, а поскольку DispatcherTimer подключен к диспетчеру по умолчанию, вы просто перегрузили очередь диспетчера потоков пользовательского интерфейса большим количеством работы.

Один полезный тест — просто измерьте, как долго в среднем выполняется метод timer_yaw_tick(), поставив в начале и в edn следующее:

// start
var watch = Stopwatch.StartNew();

// end
watch.Stop();

// see value of the watch.ElapsedMilliseconds property

Я бы рекомендовал использовать класс System.Threading.Timer для периодического планирования заданий и отправки обновлений элементов управления пользовательского интерфейса в поток пользовательского интерфейса, используя Dispatcher.Invoke()/Dispatcher.BeginInvoke()

person sll    schedule 06.08.2012
comment
так какой класс таймера подойдет в этом случае? - person Umer Qureshi; 06.08.2012
comment
Можете ли вы порекомендовать пример класса System.Threading.Timer .. я не использовал его раньше - person Umer Qureshi; 06.08.2012