Действие каждые x мс, сохраняя UI отзывчивым и избегая многопоточности - PullRequest
1 голос
/ 08 ноября 2011

У меня есть библиотека классов на C ++ / Cli с классом Entity.Позиции сущностей можно изменить с помощью Jump(destination) (внутри класса сущностей).

Помимо немедленного изменения позиции с помощью Jump(destination) Мне нужно реализовать движения с помощью Move(destination).Все точки Движения хранятся в Trajectory -классе, и в настоящее время я реализую Движение в виде серии Прыжков к этим точкам с определенной задержкой:

for(int i = 0; i < trajectory->NumberOfSteps; i++)
{
    // perform one step
    destination = trajectory->Steps[i];
    receivingEntity->Jump(destination);

    // wait
    System::Threading::Thread::Sleep(timePerStep));
}

Я звоню Move() изприложение Windows Forms C #.Моя текущая реализация, очевидно, позволяет моему пользовательскому интерфейсу (который находится в том же потоке) зависать во время выполнения Motion.

Я ищу способ реагировать на мой пользовательский интерфейс во время Движения, чтобы можно было выполнять такие действия, как нажатие кнопки отмены, чтобы остановить движение.У меня была идея сделать что-то вроде «после каждого шага отвечать на любое событие в очереди событий (например, CancelButtonClicked)».Но как мне сделать это в .net?

for(int i = 0; i < trajectory->NumberOfSteps; i++)
{
    // perform one step
    destination = trajectory->Steps[i];
    receivingEntity->Jump(destination);

    ProcessEventQueue()      // How can I do this?

    // wait
    System::Threading::Thread::Sleep(timePerStep));
}

Любое решение для моей идеи или лучшие идеи?

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

наилучшими пожеланиями richn

Ответы [ 3 ]

1 голос
/ 08 ноября 2011

Если это приложение WinForms, вы можете позвонить Application.DoEvents. Это, конечно, откроет вам проблемы повторного входа, , как описано в документации MSDN .

В качестве альтернативы, возможно, лучше использовать System.Windows.Forms.Timer .

Начните отсчет каждые n миллисекунд, сделайте Прыжок на каждом тике и остановите его, когда вы завершили свою траекторию или пользователь отменил.

0 голосов
/ 10 ноября 2011

На вашем месте я бы использовал многопоточность.

  • Делайте то, что вы делаете сейчас (действие, затем сон) в отдельном потоке
  • Предостережение заключается в том, что выможет обновлять графический интерфейс только из одного потока за раз, поэтому, если вы хотите обновить графический интерфейс из другого потока, вам придется использовать диспетчер.

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

0 голосов
/ 08 ноября 2011

Я бы тоже пошел с классом Timer.

Но вы можете заставить сообщения рисования повторять создание цикла сообщений.Мои WinForms немного ржавые, но достаточно вызвать Invalidate и затем перехватить сообщение / событие рисования.Затем вы можете отслеживать истекшее время с помощью таймера или вычитания DateTime.

...