2009-11-24 2 views
1

UDP를 통해 이름과 IP 주소를 브로드 캐스팅하는 다른 내부 시스템에 액세스하려는 내부 응용 프로그램을 만들려고합니다. UDP 메시지를 15 초 동안 500ms마다 폴링하고 UDP 메시지를 구문 분석 한 다음 감지 된 시스템의 이름을 대화 상자의 ListBox에 추가하여 실시간으로 업데이트하는 멀티 스레드 대화 상자를 만들려고합니다. 이미 UDP 스캐닝 코드를 테스트하고 완료 한 경우 유일한 문제는 스레드에서 ListBox를 업데이트하는 것입니다. ListBox의 Item 또는 ItemSource 속성에 액세스하려고 할 때마다 System.InvalidOperationException이 발생합니다. "다른 스레드가 소유하고 있기 때문에 호출하는 스레드가이 개체에 액세스 할 수 없습니다."C#에서 WPF GUI에 대한 다중 스레드 액세스

관련 스택 추적 부분이 상관없이 내가 ObservableCollection에 사용하고 있는지의 발생

at System.Windows.Threading.Dispatcher.VerifyAccess() 
    at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value) 
    at System.Windows.Controls.ItemsControl.set_ItemsSource(IEnumerable value) 

(내가 아는 컬렉션 유형과는 상관이 없음)하는 HashSet의 또는 기타 객체입니다. 아무도 다른 스레드에서 GUI에 액세스하는 것을 도와 줄 수 있습니까?

답변

5

다른 스레드에서 gui에 안전하게 액세스 할 수 없습니다. 모든 호출은 Invoke 호출을 통해 주 스레드에서 실행되도록 디스패치되어야합니다. 이것은 Windows가 수년간에 걸친 기존의 전화 끊기입니다. 여기

당신이 시작할 수 있어야 코드 조각의 ... 은 (여기 : http://social.msdn.microsoft.com/forums/en-US/wpf/thread/360540eb-d756-4434-86f9-a3449f05eb55/를)

if(textbox.Dispatcher.CheckAccess()) 
{ 
    // The calling thread owns the dispatcher, and hence the UI element 
    textbox.AppendText(...); 
} 
else 
{ 
    // Invokation required 
    textbox.Dispatcher.Invoke(DispatcherPriority.Normal, [delegate goes here]); 
} 

여기에 추가 설명이 있습니다 : http://channel9.msdn.com/forums/TechOff/251835-WPF-Invoke-and-Anonymous-delegates/

+0

와우, 놀랍도록 유용한 답변이었고, 트릭을 만들었습니다. 정말 고맙습니다. 내가 할 수 있다면 최대 12 번 더 대답 해 주겠다고. –

+0

또한 Dispatcher.BeginInvoke/EndInvoke 패턴을 사용하여 UI 스레드로 비동기 적으로 디스패치 할 수 있습니다. –

2

앤드류가 이미 말했듯이, 당신은 동기화해야이 스레드를 통해 GUI에 액세스 할 수 있습니다 (이는 그저 그런 방식입니다 - 그것에 대해 많은 것을 할 수는 없습니다).

그러나 Dispatcher은 WPF 관련 동기화 메커니즘입니다. 보다 일반적인 접근법을 고수하고 싶다면 System.Threading.SynchronizationContext 클래스를 살펴보십시오.

관련 문제