2012-06-04 2 views
2

UI를 업데이트하는 콜백을 사용하여 폼 응용 프로그램에 여러 개의 System.Threading.Timers가 있습니다 ... 성공적으로 - 즉 오류가 발생하지 않습니다.System.Threading.Timer 콜백이 UI를 성공적으로 업데이트하는 이유는 무엇입니까?

내가 UI 스레드가 아닌 다른 스레드에서 UI를 업데이트해서는 안된다는 것을 알기 전에 이전에 작성했었다.

이제 이러한 개별 threading.timer 스레드에서 UI를 업데이트 할 때 크로스 스레드 예외가 발생하지 않는 이유에 대해 혼란 스럽습니다.

UI 업데이트가 UI 스레드에서 호출되도록 이러한 콜백을 변경하려고합니다. 그러나 이것이 왜 작동하는지 궁금합니다.

편집 : 내 응용 프로그램은 WinForms 응용 프로그램입니다.

+0

WinForms 또는 WPF? – Tudor

+0

@ 튜더보기 편집 –

+0

몇 가지 코드를 보여줄 수 있습니까 ?? 나는 당신이 가지고있는 대답처럼 운이 좋았던 것만으로도이 일이 순조 롭지 않다고 생각합니다. – gbianchi

답변

2

UI 업데이트가 UI 스레드에서 호출되도록 이러한 콜백을 변경 하겠지만, 왜 이렇게 작동하는지 궁금합니다.

이것은 Windows Forms의 경우 순전히 운이 좋습니다. 백그라운드 스레드에서 UI를 업데이트해도 일관되게 작동하지 않지만 때때로 throw되지는 않습니다. 특히, CheckForIllegalCrossThreadCalls이 false 인 경우 동작이 종종 잘못 되긴하지만 때로는 "작동"하고 throw하지 않습니다. 일부 컨트롤은 항상 모든 속성을 검사하지는 않으므로 일부 항목은 제대로 작동하지 않을 수도 있지만 일반적으로 나중에 진단 및 수정하기가 어려운 버그가 발생하기 때문에 일부 항목은 "작동"합니다.

참고 : WPF 인 경우 배경 스레드에서 UI를 효과적으로 업데이트하면서 UI에 바인딩 된 항목의 값을 변경할 수 있습니다. WPF 바인딩 시스템은이를 자동으로 UI 스레드로 마샬링합니다. 그러나 컬렉션의 일부를 변경하는 것은 작동하지 않습니다.

1

또한 WinForms에서도이 기능을 경험했습니다. 여기를 참조하십시오 : Can you access UI elements from another thread? (get not set) 제 생각에는 "마법"("무작위 방식"으로 읽음)에 의해 작동하며, 실제로 그것을 수행하기위한 초대장으로 받아 들여서는 안됩니다. 이것은 결코 GUI를 업데이트하는 thread-safe 한 방법이 아닙니다. 때때로이 프로그램은 불평하지 않습니다.

1

.NET 1.0 및 1.1에서는 스레드 간 검사가 수행되지 않으므로 InvalidOperationException을 얻을 수 없습니다. (예 : 크로스 스레드 업데이트를 수행하면 "응용 프로그램 충돌을 포함하여 예상치 못한 결과가 나오는 경우가 많습니다" .

.NET 2.0 이상에서는 정적 속성 Control.CheckForIllegalCrossThreadCalls의 값에 따라 스레드 간 검사가 수행됩니다. 기본값은 Debugger.IsAttached 정적 속성 (디버거가 프로세스에 연결되어 있는지 여부를 나타냄)에서 초기화됩니다. 즉, 응용 프로그램이 자체적으로 실행될 때 크로스 스레드 검사가 수행되지 않습니다 (Visual Studio 또는에 연결된 다른 디버거없이). 그것).

이 설정은 물론 참조 된 라이브러리를 포함하여 사용자 코드로 덮어 쓸 수 있습니다.

0

저는 이것이 당신이 만들고있는 타이머의 유형과 관련이 있다고 생각합니다. 당신은 UI를 업데이트 할 경우

System.Timers.Timer; 
    System.Windows.Forms.Timer 

이 둘 사이에 뚜렷한 차이가 있습니다에서, System.Timers.Timer 예외를 던질 것이며, System.Windows.Forms.Timer가되지 않습니다 두 가지 유형이 있습니다. using 문을 사용하는 경우 : "System.Windows.Forms 사용"및 단순히 "타이머"가 System.Timers.Timer와 분명히 다른 Windows.Forms.Timer가됩니다.

후드 (전) System.Windows.Forms.Timer는 WM_TIMER 메시지를 트래핑 중이므로 GUI를 업데이트하는 스레드에 있습니다.

관련 문제