Dispatcher.CurrentDispatcher 대 Application.Current.Dispatcher


78

Dispatcher.CurrentDispatcher(in System.Windows.Threading)과 Application.Current.Dispatcher(in System.Windows) 의 차이점은 무엇입니까 ?

내 직감은 Application.Current.Dispatcher변경되지 않고 현재 응용 프로그램의 모든 스레드에 전역 적 Dispatcher.CurrentDispatcher이며 Dispatcher호출 된 스레드 에 따라 의 새 인스턴스를 만들 수 있다고 말합니다.

그 맞습니까?

그렇다면 Dispatcher.CurrentDispatcher주로 다중 스레드 UI를위한 목적 입니까?

답변:


98

내 직감에 따르면 Application.Current.Dispatcher는 변경되지 않고 현재 응용 프로그램의 모든 스레드에 전역 적이며 Dispatcher.CurrentDispatcher는 호출 된 스레드에 따라 Dispatcher의 새 인스턴스를 만들 수 있습니다.

맞아요.

또한 Dispatcher.CurrentDispatcher비 UI 스레드 에서 액세스 하는 데 아무런 의미가 없습니다 . 를 호출하지 않으면 아무것도하지 않으며 Dispatcher.Run무한 메시지 루프로 들어가는 것은 작업자 스레드 내에서 수행하려는 작업이 아닙니다.

그래서:

  • 가장 일반적인 시나리오에서는 앱이 단 하나의 UI 스레드를 가지고, Application.Current.DispatcherDispatcher.CurrentDispatcherUI 스레드 내에서 동일한 인스턴스를 반환합니다. 사용하는 것은 단순히 선호도의 문제입니다.

  • 앱에 둘 이상의 UI 스레드가있는 경우 각 DispatcherObject스레드는 생성시 생성 된 UI 스레드의 디스패처와 영구적으로 연결됩니다. 이 경우 Application.Current.Dispatcher애플리케이션이 생성 된 스레드의 디스패처를 참조합니다. 다른 UI 스레드가 소유 한 컨트롤에 메시지를 게시하는 데 사용할 수 없습니다.


2
설명 해주셔서 감사합니다. "Dispatcher.Run을 호출하지 않으면 아무 일도하지 않습니다"라는 의미는 무엇입니까? UI가 아닌 스레드에서 CurrentDispatcher를 사용했으며 Invoke는 실제로 대리자를 호출합니다. 델리게이트가 단순히 호출 스레드에서 호출된다는 의미입니까?
ken

2
@ken : Invoke및 친구들은 일반적으로 Win32 메시지에 메서드 호출을 "패키지"(원하는 경우 마샬링)하고 메시지 루프 (Dispatcher 루프)가 결국 메시지를 추출하고 호출을 실행하는 메시지 큐에 게시합니다. (당신이 그 루프 인 경우에는 디스패처 루프가 없기 때문에 당신의 코드가 실행되지 않을 것이다) 호출은 실제로 일어나지 않을 것입니다. 따라서 Invoke먼저 CurrentDispatcher최적화로 스레드에 이미 있고 마샬링 대신 현장에서 호출을 실행하는지 먼저 확인 한다고 가정합니다 . 을 확인하여이를 확인할 수 있습니다 Thread.ManagedThreadId.
Jon

다른 UI 스레드가 소유 한 컨트롤에 메시지를 게시하는 데 사용할 수 없습니다. 그렇다면 평균적인 WPF 애플리케이션에는 몇 개의 UI 스레드가 있습니까?

@Will : One : "앱에 UI 스레드가 하나만있는 경우 (대부분) ..." . 더 많은 설명이 필요하다고 생각하십니까?
Jon

1
@Will : 관련 부품의 가시성을 높이기 위해 편집되었습니다. 알려 줘서 고마워.
Jon

21

간단히 말해서 ...

Dispatcher.CurrentDispatcher현재 스레드 의 디스패처 가져옵니다 . 따라서 백그라운드 프로세스에서 UI 스레드의 Dispatcher를 찾고 있다면 이것을 사용하지 마십시오.

Application.Current.Dispatcher 이것은 유일한 Application 인스턴스를 회전시키는 스레드이기 때문에 항상 UI 스레드의 디스패처를 제공합니다.


9

내 직감에 따르면 Application.Current.Dispatcher는 변경되지 않고 현재 응용 프로그램의 모든 스레드에 전역 적이며 Dispatcher.CurrentDispatcher는 호출 된 스레드에 따라 Dispatcher의 새 인스턴스를 만들 수 있습니다.

맞습니다 Application.Current.Dispatcher.은 현재 스레드의 디스패처가되도록 구성시 할당되는 응용 프로그램의 인스턴스 속성입니다. 그리고의 문서가 Dispatcher.CurrentDispatcher지적했듯이 :

현재 실행중인 스레드의 Dispatcher를 가져오고 스레드와 아직 연결되지 않은 경우 새 Dispatcher를 만듭니다.


그렇다면 Dispatcher.CurrentDispatcher의 목적은 주로 다중 스레드 UI 용입니까?

아마도 작업을 디스패치하려는 UI 요소가 일반적으로 없기 때문에 백그라운드 스레드의 디스패처를 얻는 데 사용되지 않았습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.