2010-05-05 1 views
1

У меня странное поведение в моем графическом интерфейсе. Если пользователь выдает много событий за короткое время, бывает, что метод обработчика запущенного события прерывается другим методом обработчика событий. Поскольку все работает в одном потоке (поток графического интерфейса), все должно выполняться последовательно, и прерывание не должно быть возможным, или я что-то неправильно понимаю?Возможно ли, что событие GUI прерывает выполнение кода из потока GUI для выполнения собственного метода обработчика событий?

Спасибо за ваш совет, Eny

+0

Образцы данных событий? Например, вы не говорите об одном событии таймера? –

+1

Вы правы, поток GUI должен выполнять вещи последовательно. Откуда вы знаете, что эти перерывы происходят? – Paolo

+0

@Benjamin Нет никакого таймера, я проверил его уже, он действительно находится в той же теме. Эти события являются, например, узел фокусировки изменен внутри элемента управления списком дерева. @Paolo Я регистрирую, что происходит, в том числе. информация о потоках и т. д. И я получаю неправильные состояния приложений, которые не могут произойти, если они выполняются последовательно. – Enyra

ответ

4

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

Поток GUI может быть прерван, но только для запуска другого потока, он не будет повторно вводить поток GUI для обработки другого события. В потоке есть только один указатель инструкции и, следовательно, может быть только в одном месте в коде, он не может быть прерван сам по себе.

Если вы испытываете что-то похожее на то, что поток графического интерфейса повторно вводится, причина в другом.

GUI thead может, однако, «прервать» себя, вызвав метод Application.DoEvents.

+0

Application.DoEvents - хороший совет, я должен искать код, если он используется где-то. – Enyra

+0

Да, это было, спасибо. – Enyra

3

Вы правы, в однопоточном приложении событие должно запускаться последовательно. Существует несколько исключений:

  1. Событие запускается и вызывает первый обработчик событий в своем списке подписчиков. Обработчик событий запускает собственное событие, которое вызывает другие обработчики событий. В этом случае, казалось бы, событие было прервано, но это не так. Когда обработчик исходного события завершится, вызывается следующий обработчик событий в списке.

  2. Обработчик события вызывает метод Application.DoEvents(). Это приостановит текущее событие и обработает любые сообщения, ожидающие в очереди сообщений (которые обычно запускают собственные события), и когда он завершит обработку всех сообщений, он вернется к событию. Проблема может возникнуть, когда Application.DoEvents() вызывает рекурсивный вызов вызываемому ему событию в результате запуска события из одного из обработанных им сообщений.

  3. Обработчики событий могут выполняться на разных потоках. Некоторые события не запускаются в потоке пользовательского интерфейса и могут запускаться в их собственном потоке. Это может привести к тому, что события будут выведены из строя и прервут друг друга в контексте контекста потока. Убедитесь, что события, которые вы потребляете, запускаются в потоке пользовательского интерфейса, а если нет, то Control.Invoke() их на поток пользовательского интерфейса. Пример события, которое запускается в отдельном потоке, возможно, если вы не знаете об этом, это событие System.Threading.Timer.Elapsed.

+0

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

Смежные вопросы