Dispatcher.Invoke를 사용하여 주 스레드가 아닌 스레드에서 WPF 컨트롤 변경
나는 최근에 WPF에서 프로그래밍을 시작했고 다음과 같은 문제에 부딪 혔습니다. 방법을 사용하는 Dispatcher.Invoke()
방법 을 이해하지 못합니다 . 스레딩 경험이 있으며 방금 사용한 몇 가지 간단한 Windows Forms 프로그램을 만들었습니다.
Control.CheckForIllegalCrossThreadCalls = false;
예, 그것은 꽤 절름발이는 것을 알고 있지만 이것은 단순한 모니터링 응용 프로그램이었습니다.
사실은 이제 백그라운드에서 데이터를 검색하는 WPF 응용 프로그램을 만들고 있습니다. 새 스레드를 시작하여 웹 서버에서 데이터를 검색하는 호출을 시작합니다. 이제 WPF 양식에 표시하고 싶습니다. 문제는이 스레드에서 어떤 제어도 설정할 수 없다는 것입니다. 레이블이나 그 어떤 것도 아닙니다. 이 문제를 어떻게 해결할 수 있습니까?
답변 설명 :
@Jalfp :
데이터를 얻을 때 '새 트레드'에서이 Dispatcher 메서드를 사용합니까? 아니면 백그라운드 작업자가 데이터를 검색하고 필드에 넣은 다음이 필드가 채워질 때까지 대기하고 디스패처를 호출하여 검색된 데이터를 컨트롤에 표시하는 새 스레드를 시작해야합니까?
첫 번째는 Dispatcher가 긴 차단 작업 (예 : WebServer에서 데이터 검색 ...)을 실행하도록 설계되지 않았 음을 이해하는 것입니다. UI 스레드에서 실행될 작업 (예 : 진행률 표시 줄의 값 업데이트)을 실행하려는 경우 Dispatcher를 사용할 수 있습니다.
할 수있는 일은 백그라운드 작업자에서 데이터를 검색하고 ReportProgress 메서드를 사용하여 UI 스레드의 변경 사항을 전파하는 것입니다.
실제로 Dispatcher를 직접 사용해야하는 경우 매우 간단합니다.
Application.Current.Dispatcher.BeginInvoke(
DispatcherPriority.Background,
new Action(() => this.progressBar.Value = 50));
japf가 올바르게 대답했습니다. 여러 줄로 된 동작을보고있는 경우를 대비하여 아래와 같이 작성할 수 있습니다.
Application.Current.Dispatcher.BeginInvoke(
DispatcherPriority.Background,
new Action(() => {
this.progressBar.Value = 50;
}));
성능에 대해 알고 싶은 다른 사용자를위한 정보 :
고성능을 위해 코드를 작성해야하는 경우 먼저 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를 사용하는 경우 및없는 경우)를 만드는 옵션이 있습니다. 디스패처의 이러한 측면을 살펴 봐야하는 경우는 드문 경우입니다.
스레드가 실행 중이고 현재 스레드에 의해 차단 된 메인 UI 스레드를 실행하려면 다음을 사용하십시오.
현재 스레드 :
Dispatcher.CurrentDispatcher.Invoke(MethodName,
new object[] { parameter1, parameter2 }); // if passing 2 parameters to method.
기본 UI 스레드 :
Application.Current.Dispatcher.BeginInvoke(
DispatcherPriority.Background, new Action(() => MethodName(parameter)));
'code' 카테고리의 다른 글
신속하게 NSUserdefaults에서 배열 배열을 저장하고 읽는 방법은 무엇입니까? (0) | 2020.11.03 |
---|---|
iOS Swift에서 이미지에 텍스트를 어떻게 추가합니까? (0) | 2020.11.03 |
iOS UIDevice 방향 감지 (0) | 2020.11.03 |
@synthesize를 언제 명시 적으로 사용해야합니까? (0) | 2020.11.03 |
필터 Android가있는 사용자 정의 Listview 어댑터 (0) | 2020.11.03 |