Отключить все события в форме Windows - PullRequest
4 голосов
/ 01 октября 2010

Есть ли способ временно отключить ВСЕ события в форме Windows?

У меня есть ситуация, когда обработка во вторичном потоке повреждена событиями в основном потоке. (События основного потока изменяют содержимое элементов управления, которые привязаны к данным к переменным, используемым вторичным потоком.) Ищем способ «заблокировать» форму до завершения обработки во вторичном потоке. (Очевидно, что перемещение обработки в основной поток сделало бы это - но это также "заморозило бы" пользовательский интерфейс, что тоже не то, что мне нужно.)

Ответы [ 5 ]

2 голосов
/ 01 октября 2010

Несколько разных опций должны позволить вам решить эту проблему:

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

Я бы выбрал первый вариант, возможно, в сочетании с установкой курсора на песочные часы и / или установкой сообщения в строке состояния. Это просто, это работает, и это не заставляет фактический пользовательский интерфейс зависать. Я бы избегал третьего варианта, так как он «нарушит» поведение вашей формы во время ее работы. Эффективность второго варианта зависит от того, как вы его реализуете; это может очень легко заморозить пользовательский интерфейс, что вы не хотите делать ..

2 голосов
/ 01 октября 2010

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

И у него есть стандартное решение, используйте ключевое слово lock.

Если этонецелесообразно, потому что пользователю необходимо изменить несколько элементов управления, прежде чем вы сможете снова выполнить запрос, а затем вам нужно прервать работающий поток.BackgroundWorker.CancelAsync, например.Если это нецелесообразно, поскольку для отмены запроса требуется слишком много времени, необходимо установить для свойства Enabled для элементов управления значение false во время выполнения запроса.

1 голос
/ 16 ноября 2010

Спасибо всем за вашу прекрасную помощь. Действительно помог процесс принятия решений. Привет всем. Закончилось с помощью блокировки. (То есть оператор if в начале каждого обработчика событий проверяет состояние блокировки перед продолжением.) Утомительно и не все это "круто" технически, но просто и работает.

1 голос
/ 01 октября 2010

Если вы хотите подавить все события, возникающие в результате PostMessage , вы можете реализовать интерфейс IMessageFilter и использовать AddMessageFilter .

Это, вероятно, заманивает в ловушку все события, в которых вы заинтересованы.Он не будет перехватывать все, например, событие, полученное в результате SendMessage .Чтобы перехватить абсолютно все, вам понадобится ловушка приложения для потока .

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

1 голос
/ 01 октября 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...