Вопрос по .net, wpf – Dispatcher.CurrentDispatcher против Application.Current.Dispatcher

68

Каковы различия междуDispatcher.CurrentDispatcher (вSystem.Windows.Threading) а такжеApplication.Current.Dispatcher (вSystem.Windows)?

Моя кишка говорит мне, чтоApplication.Current.Dispatcher никогда не изменится и является глобальным для всех потоков в текущем приложении, в то время какDispatcher.CurrentDispatcher может создать новый экземплярDispatcher в зависимости от потока, из которого он был вызван.

Это верно?

Если это так, является цельюDispatcher.CurrentDispatcher в первую очередь для многопоточного интерфейса?

Ваш Ответ

3   ответа
18

Dispatcher.CurrentDispatcher получает диспетчерfor the current thread, Поэтому, если вы ищете Dispatcher потока пользовательского интерфейса из фонового процесса, не используйте его.

Application.Current.Dispatcher всегда будет выдавать вам диспетчер потока пользовательского интерфейса, так как этот поток раскручивает единственный экземпляр приложения.

8

and is global to all threads in the current application, while Dispatcher.CurrentDispatcher may create a new instance of Dispatcher depending on the thread from which it was called.

Это правильно,Application.Current.Dispatcher является свойством экземпляра приложения, которое при построении назначается диспетчером текущего потока. И как документацияDispatcher.CurrentDispatcher указывает на то:

Gets the Dispatcher for the thread currently executing and creates a new Dispatcher if one is not already associated with the thread.

If it is, is the purpose of Dispatcher.CurrentDispatcher primarily for multi-threaded UI?

Возможно, я не сталкивался с каким-либо использованием при получении диспетчера фонового потока, поскольку у вас обычно нет принадлежащих им элементов пользовательского интерфейса, которым вы можете захотеть отправлять операции.

80

and is global to all threads in the current application, while Dispatcher.CurrentDispatcher may create a new instance of Dispatcher depending on the thread from which it was called.

Это правильно.

Кроме того, нет никакого смысла в доступеDispatcher.CurrentDispatcher из не-пользовательского интерфейса потока. Это ничего не сделает, если вы не позвонитеDispatcher.Runи вход в бесконечный цикл сообщений - это не то, что вы хотите делать из рабочих потоков.

Так:

In the most common scenario, where your app only has a single UI thread, Application.Current.Dispatcher and Dispatcher.CurrentDispatcher from within the UI thread will return the same instance. Which one you use is simply a matter of preference.

If your app has more than one UI thread then each DispatcherObject will be permanently associated with the dispatcher of the UI thread it was created in upon construction. In this case, Application.Current.Dispatcher will refer to the dispatcher of the thread your application spawned with; you will not be able to use it to post messages to controls owned by your other UI threads.

you will not be able to use it to post messages to controls owned by your other UI threads.  Итак, сколько потоков пользовательского интерфейса существует в вашем обычном приложении WPF?
@Will: отредактировано для увеличения видимости соответствующей части. Спасибо, что дали мне знать.
@Will: один:"If your app only has one UI thread (most likely)...", Как вы думаете, нужно больше разъяснений?
Спасибо за объяснение, но что вы подразумеваете под "quot; Это ничего не даст, если вы не вызовете Dispatcher.Run & quot ;? Я использовал CurrentDispatcher из потока, не являющегося пользовательским интерфейсом, и Invoke действительно вызывает делегат. Вы имеете в виду, что делегаты будут просто вызываться в вызывающем потоке? ken
@ken:Invoke и друзья обычно "пакет" (маршал, если хотите) вызов метода в сообщении Win32 и отправка его в очередь сообщений, из которой цикл сообщений (диспетчерский цикл) в конечном итоге извлекает его и выполняет вызов. Так как нет диспетчерского цикла (если вы были в этом циклеyour код не будет выполняться) вызов на самом деле никогда не произойдет. Итак, я предполагаю, чтоInvoke сначала проверяет, если вы уже вCurrentDispatcher поток как оптимизация, и если вы выполняете вызов на месте, а не маршалинг. Вы можете убедиться в этом, проверивThread.ManagedThreadId.

Похожие вопросы