2009-10-29 2 views
60

저는 최근 WPF에서 프로그래밍을 시작했으며 다음 문제에 부딪 혔습니다. 나는 Dispatcher.Invoke() 방법을 사용하는 방법을 이해하지 못한다. 나는 스레딩 경험을하고 난 몇 가지 간단한 윈도우 네, 그건 꽤 절름발이 그러나이 간단한 모니터링 애플리케이션 있었다 알고 난 그냥Dispatcher.Invoke를 사용하여 비 메인 스레드에서 WPF 컨트롤을 변경하십시오.

Control.CheckForIllegalCrossThreadCalls = false; 

을 사용하는 프로그램을 양식 만들었습니다.

사실 이제 백그라운드에서 데이터를 검색하는 WPF 응용 프로그램을 만들고 있는데, 웹 서버에서 데이터를 검색하기 위해 새 스레드를 시작하고 지금은 WPF에 표시하려고합니다. 형태. 것은,이 스레드에서 어떤 컨트롤을 설정할 수 없습니다. 심지어 레이블이나 뭐. 이 문제를 어떻게 해결할 수 있습니까?

대답 코멘트 :
@Jalfp :
내가 데이터를 얻을 때 그래서 나는 '새로운 트레드'이 디스패처 방법을 사용합니까? 또는 배경 작업자가 데이터를 검색하여 필드에 넣고이 필드가 채워질 때까지 대기하는 새 스레드를 시작하고 검색된 데이터를 컨트롤에 표시하도록 디스패처를 호출해야합니까?

답변

145

먼저 Dispatcher가 (WebServer에서 데이터를 검색하는 것과 같이) 긴 블로킹 조작을 실행하도록 설계되지 않았다는 것을 이해해야합니다. 진행 표시 줄 값 업데이트와 같이 UI 스레드에서 실행할 작업을 실행하려는 경우 Dispatcher를 사용할 수 있습니다.

백그라운드 작업자에서 데이터를 검색하고 ReportProgress 메서드를 사용하여 UI 스레드의 변경 내용을 전파 할 수 있습니다. 당신이 정말로 직접 Dispatcher를 사용해야하는 경우

, 그것은 아주 간단 : 제대로 대답이 japf

Application.Current.Dispatcher.BeginInvoke(
    DispatcherPriority.Background, 
    new Action(() => this.progressBar.Value = 50)); 
+19

당신은 '새로운 액션 ('부분을 제거하고, 단순히 람다 식 사용 얻을 수 있습니다 내가 넣어 이유 50 – jrista

+0

그래 모르는 DispatcherPriority.Background,() => this.progressBar.Value =을 여기서 조치 : p – japf

+0

데이터를 얻을 때 '새 트레드'에서이 Dispatcher 메소드를 사용합니까? 아니면 백그라운드 작업자가 데이터를 검색하여 필드에 넣고이 필드가 나타날 때까지 대기하는 새 스레드를 시작해야합니까? 검색된 데이터를 컨트롤에 표시하도록 운영자를 호출하고 호출합니다. –

19

. 다중 행 작업을보고있는 경우 다음과 같이 작성할 수 있습니다. 성능에 대해 알고 싶은 다른 사용자

Application.Current.Dispatcher.BeginInvoke(
    DispatcherPriority.Background, 
    new Action(() => { 
    this.progressBar.Value = 50; 
    })); 

정보 : 코드의 NEED 높은 성능을 기록 할 경우 호출이되어 checkAccess 플래그를 사용하여 필요한 경우

, 먼저 확인할 수 있습니다.

if(Application.Current.Dispatcher.CheckAccess()) 
{ 
    this.progressBar.Value = 50; 
} 
else 
{ 
    Application.Current.Dispatcher.BeginInvoke(
     DispatcherPriority.Background, 
     new Action(() => { 
     this.progressBar.Value = 50; 
     })); 
} 

CheckAccess() 메서드는 Visual Studio 2015에서 숨겨져 있으므로 intellisense를 표시하지 않고 코드를 작성하면됩니다. CheckAccess는 성능에 오버 헤드가 있습니다 (수 나노초의 오버 헤드). 어떤 경우에도 '호출'을 수행하는 데 필요한 마이크로 초를 절약하고자 할 때만 더 좋습니다. 또한 UI 스레드에 있는지 여부를 확실히 호출 할 때 두 개의 메소드를 호출 할 수있는 옵션이 항상 있습니다 (invoke와 with 및 without). 드문 경우지만 디스패처 측면을보아야 할 때가 드뭅니다.

관련 문제