2009-11-23 11 views
1

Windows Forms 이벤트에 이상한 문제가 있습니다. 정확히 말하면 KryptonHeaderGroup의 ButtonSpec Click 이벤트이지만 일반 바닐라 System.Windows.Forms.Button에서도 발생합니다.Windows Forms Click 이벤트 반복 자체

click 이벤트에서 사용자 인터페이스가 중단되고 레이블과 취소 단추가 남아 있습니다. 그러면 값 비싼 LINQ 쿼리가 이전 사용자 입력에서 작성되어 컴파일되고 실행됩니다. foreach에는 실제로 쿼리를 실행하는 호출이 Application.DoEvents() 있습니다 (LINQ to objects이므로 게으름입니다). 이를 통해 사용자는 취소를 누를 수 있으며 DoEvents 이후에 취소 플래그가 테스트되고 foreach가 취소되고 일부 정리가 발생합니다. 여태까지는 그런대로 잘됐다.

그러나 처음 몇 개의 결과가 들어온 후에 취소 버튼을 누르면 (이미 레이블에 레이블이 표시됩니다) 전체 Click 이벤트 핸들러가 다시 시작됩니다. 일부 추적을 추가 한 후 이전 처리기가을 반환하기 전에 이 발생하는 것으로 보입니다. 즉, DoEvents 호출 중 하나에서 발생합니다. 버튼은 물론 다시 누르지 않습니다. 이벤트 처리기에서 버튼이 비활성화 된 경우에는 발생하지 않습니다. 그러나 버튼이 눌러지지 않았으므로 클릭 이벤트를 다시 발생시켜야합니다.

나는 당황하고 있습니다. 분명히 해결 방법은 버튼을 비활성화하는 것이지만 실제로 문제가 무엇인지 알고 싶습니다. 처리기가 완료되기 전에 DoEvents이 호출되면 이벤트 처리기를 다시 시작할 수 있습니까? 이벤트 처리기에서 DoEvents을 권장/허용하지 않습니까? 모든 이벤트 기반 응용 프로그램에서 이벤트 핸들러이기 때문에 그런데, 당신은 그것을 호출하지 않을 수 있습니다 :)이 질문에 대답해야 할 수 있습니다

추가 힌트 :

  • LINQ 쿼리이 오래 소요를 첫 번째 결과를 제공하기 전, 즉 처음으로 DoEvents 전화가 걸리기 전의 시간.
  • LINQ 쿼리는 GUI와 LINQ 쿼리가 모두 사용하는 기본 API를 방해하기 때문에 사용자가 나머지 응용 프로그램에 액세스 할 수 있도록 허용하지 않으므로 GUI 스레드에서 실행됩니다.
  • LINQ 쿼리를 별도의 응용 프로그램 도메인에로드하고 언로드 할 수 있어야한다는 것을 알고 있습니다. 그러나 일반 사용자가 실행하는 여러 가지 쿼리 만있을 것이며 결과 어셈블리는 캐시됩니다 (동일한 쿼리 문자열에 대해).
  • 중단 점을 사용하도록 설정 한 경우 (한숨 - Heisenberg, 누구?) 나중에 쿼리를 취소하는 경우 문제가 더 이상 발생하지 않습니다.

는 나는 추측은 더 클릭 또는 메시지를 처리 ​​할 수 ​​있도록

답변

3

DoEvents는 GUI 메시지를 처리합니다 :) 그냥 경우에도 행동을 설명 할 수있는 모든 작업을 주셔서 감사합니다. 이벤트 처리기에서 호출하지 말고 솔직히 사용하지 않는 것이 좋습니다. MSDN에서

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

장기 :

이 버튼을 백그라운드 스레드에서 그것을 실행보고 해제 할 장기 실행 쿼리 인 경우. 이것은 이러한 유형의 활동에 대한 일반적인 패턴입니다.

+0

DoEvents 문제는이 경우 이벤트가 한 번만 발생한다는 것입니다. 버튼을 두 번째 클릭하지 않았습니다. 나는 백그라운드 스레드와 일반적으로 동의하지만,이 애플리케이션에서는 쿼리에서 사용되는 기본 API와 애플리케이션이 스레드로부터 안전하지 않으며 메인에서 GUI 스레드로부터 액세스된다. 응용 프로그램의 일부. 메인 윈도우를 닫을 때 자동으로 쿼리를 취소 할 수있는 기회가 있다면 별도의 스레드에서 계속 시도 할 것입니다. – OregonGhost

+0

좋아, 좋지는 않지만 네가해야 할 일을해야 해. 또 다른 한가지 : 이벤트에 두 번 등록하지 않았습니까? 그렇지 않다면 Krypton 라이브러리는 반사경을 사용하여 그것이 무엇을하는지 보는 방법은 무엇입니까? –

+0

내가 말했듯이 이것은 간단한 SWF 버튼에서도 발생합니다. 그리고 확실히 한 번만 구독했습니다. 취소 단추를 반복해서 클릭하면 이벤트 처리기가 반복적으로 다시 시작되지만 한 번 완료되면 모두 완료됩니다. 완전히 중첩 된 상태로 실행됩니다. – OregonGhost