Возможно ли, что событие GUI прерывает выполнение кода из потока GUI, чтобы выполнить свой собственный метод обработчика события? - PullRequest
1 голос
/ 05 мая 2010

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

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

Ответы [ 2 ]

4 голосов
/ 05 мая 2010

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

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

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

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

3 голосов
/ 05 мая 2010

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

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

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

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

...