2009-11-23 8 views
1

У меня странная проблема с событием Windows Forms. Точнее, это событие ButtonSpec Click , но это также происходит с простой ванилью System.Windows.Forms.Button.Windows Forms Повторное событие Click

В событии клика пользовательский интерфейс сбрасывается (слева и слева от кнопки «Отмена»), а затем дорогой запрос LINQ строится из предыдущего пользовательского ввода, скомпилирован и затем исполняется. Есть Application.DoEvents() вызовов в foreach, который фактически выполняет запрос (это LINQ для объектов, поэтому он ленив). Это позволяет пользователю отменить отмену, а после DoEvents проверяется флажок отмены, а foreach отменяется, и происходит некоторая очистка. Все идет нормально.

Однако, когда я нажимаю кнопку «Отмена» после появления первых нескольких результатов (метка показывает, сколько их уже существует), весь обработчик событий Click перезапускается! После добавления некоторых трасс, кажется, что это происходит , прежде чем предыдущий обработчик вернется. Другими словами, это происходит в одном из вызовов DoEvents. Кнопка, конечно, не нажата снова. Этого не происходит, если кнопка отключена в обработчике событий. Но поскольку кнопка не нажата, она не должна запускать событие Click, если это так?

Я сбит с толку. Очевидно, что обходным путем является отключение кнопки, но я хотел бы знать, что может быть настоящей проблемой здесь. Можно ли перезапустить обработчик событий, если вызывается DoEvents до завершения обработки обработчика? Является ли вызов DoEvents не рекомендованным/разрешенным в обработчиках событий? Но, так как все это обработчик события в приложении событийного, вы никогда не мог назвать это :)

Дополнительные подсказки, которые могут потребоваться для ответа на этот вопрос:

  • Запрос LINQ берет длинный прежде чем подавать первые результаты, т.е. до первого вызова DoEvents.
  • Запрос LINQ выполняется в потоке графического интерфейса пользователя, поскольку не имеет смысла разрешать пользователю доступ к остальному приложению, поскольку доступ будет мешать базовому API как GUI, так и запросу LINQ.
  • Я знаю, что я должен загрузить запрос LINQ в отдельный домен приложения и выполнить его там, чтобы иметь возможность его выгружать. Но типичный пользователь будет иметь несколько запросов, и собранная сборка будет кэширована (для той же строки запроса).
  • Проблема не возникает, если у меня либо есть точка останова включена (sigh - Гейзенберг, кто-нибудь?), Или если я отмене позже во время запроса.

Я ценю все, что бы объяснить поведение, даже если это просто спекуляция :)

ответ

3

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

Из MSDN: Calling this method can cause code to be re-entered if a message raises an event.

Долговременные:

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

+0

Проблема с DoEvents заключается в том, что в этом случае он снова запускает событие, которое произошло только один раз. Второе нажатие на кнопку не было. Я согласен с основной темой в целом, однако я не делал этого в этом приложении, так как базовый API, который используется в запросе, и приложение не являются потокобезопасными, и он доступен из потока графического интерфейса в любом случае в главном часть приложения. Я думаю, что все равно попробую сделать это в отдельном потоке, если скорее для возможности автоматического запроса запроса при закрытии главного окна. – OregonGhost

+0

Хорошо, что это нехорошо, но вы должны делать то, что вам нужно. Другое, хотя: Вы уверены, что не подписались на мероприятие дважды? В противном случае, как насчет библиотеки Криптона, как использовать рефлектор, чтобы увидеть, что он делает? –

+0

Как я уже сказал, это происходит и с простой кнопкой SWF, и я определенно подписался один раз. Если я повторно нажимаю кнопку «Отмена», она будет повторно перезапускать обработчик событий, но все они будут завершены после того, как они пройдут один раз (они выполнены полностью вложенными). – OregonGhost

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