Событие Windows Forms Click повторяется
У меня странная проблема с событием Windows Forms. Чтобы быть точным, это событие ClickSpec Click KryptonHeaderGroup, но это также происходит с простой ванилью System.Windows.Forms.Button
,
В событии click пользовательский интерфейс отключается (остается метка и кнопка отмены), а затем на основе предыдущего ввода пользователя формируется дорогой запрос LINQ, который компилируется и затем выполняется. Есть Application.DoEvents()
вызовы в foreach, который фактически выполняет запрос (это LINQ к объектам, поэтому он ленив). Это позволяет пользователю нажать кнопку отмены, а после DoEvents
, флаг отмены проверяется, и foreach отменяется, и происходит некоторая очистка. Все идет нормально.
Однако, когда я нажимаю кнопку "Отмена" после появления первых нескольких результатов (метка показывает, сколько их уже есть), весь обработчик события Click перезапускается! Кажется, что после добавления некоторых трасс это происходит до того, как предыдущий обработчик возвращается. Другими словами, это происходит в одном из DoEvents
звонки. Кнопка, конечно, больше не нажимается. Этого не происходит, если кнопка отключена в обработчике событий. Но так как кнопка не нажата, она не должна снова запускать событие Click, не так ли?
Я сбит с толку. Очевидно, что обходной путь - отключить кнопку, но я хотел бы знать, в чем здесь может быть проблема. Можно ли перезапустить обработчик события, если DoEvents
вызывается до завершения обработчика? Звонит DoEvents
не рекомендуется / разрешено в обработчиках событий? Но тогда, поскольку в приложении, управляемом событиями, все является обработчиком событий, вы никогда не сможете вызвать его:)
Дополнительные подсказки, которые могут потребоваться для ответа на этот вопрос:
- Запрос LINQ занимает много времени, прежде чем предоставить первые результаты, т. Е. До первого
DoEvents
звонок сделан. - Запрос LINQ выполняется в потоке графического интерфейса, потому что не имеет смысла разрешать пользователю доступ к остальному приложению, поскольку доступ будет мешать основному API, как GUI, так и использованию запроса LINQ.
- Я знаю, что должен загрузить запрос LINQ в отдельный домен приложения и выполнить его там, чтобы иметь возможность выгрузить его. Но будет только несколько различных запросов, выполняемых обычным пользователем, и результирующая сборка кэшируется (для той же строки запроса).
- Проблема больше не возникает, если у меня либо включена точка останова (вздох - Гейзенберг, кто-нибудь?), Либо если я отменю позже во время запроса.
Я ценю все, что объясняет поведение, даже если это всего лишь предположение:)
1 ответ
DoEvents будет обрабатывать сообщения с графическим интерфейсом, поэтому он будет обрабатывать любые дальнейшие клики или сообщения. Я бы порекомендовал вам не вызывать его в обработчике событий, и если честно, я бы вообще не использовал его.
Из MSDN: вызов этого метода может привести к повторному вводу кода, если сообщение вызывает событие.
Долгосрочный
Если это длительный запрос, вы хотите посмотреть его в фоновом потоке и отключить кнопку. Это общая схема для этого вида деятельности.