Dispatcher.CurrentDispatcher против Application.Current.Dispatcher

В чем разница между Dispatcher.CurrentDispatcherSystem.Windows.Threading) и Application.Current.DispatcherSystem.Windows)?

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

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

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


person ken    schedule 04.05.2012    source источник


Ответы (3)


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

Это верно.

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

So:

person Jon    schedule 04.05.2012
comment
Спасибо за объяснение, но что вы имеете в виду под «Он ничего не сделает, если вы не вызовете Dispatcher.Run»? Я использовал CurrentDispatcher из потока, отличного от пользовательского интерфейса, и Invoke действительно вызывает делегат. Вы имеете в виду, что делегаты будут просто вызываться в вызывающем потоке? - person ken; 04.05.2012
comment
@ken: Invoke и друзья обычно упаковывают (сортируют, если хотите) вызов метода в сообщение Win32 и отправляют его в очередь сообщений, из которой цикл сообщений (цикл диспетчера) в конечном итоге извлекает его и выполняет вызов. Поскольку диспетчерского цикла нет (если бы вы были в этом цикле, ваш код не выполнялся бы), вызов на самом деле никогда не выполнялся бы. Поэтому я предполагаю, что Invoke сначала проверяет, находитесь ли вы уже в потоке CurrentDispatcher в качестве оптимизации, и если вы выполняете вызов на месте вместо маршалинга. Вы можете убедиться в этом, проверив Thread.ManagedThreadId. - person Jon; 04.05.2012
comment
вы не сможете использовать его для отправки сообщений элементам управления, принадлежащим другим вашим потокам пользовательского интерфейса. Итак, сколько потоков пользовательского интерфейса имеется в вашем обычном приложении WPF? - person ; 30.04.2014
comment
@Will: Один: Если ваше приложение имеет только один поток пользовательского интерфейса (скорее всего).... Как вы думаете, нужно больше пояснений? - person Jon; 30.04.2014
comment
@Jon: Ну, учитывая, что это меня смутило, да. Я не видел строки, которую вы цитируете... - person ; 30.04.2014
comment
@Will: отредактировано для повышения видимости соответствующей части. Спасибо, что дал мне знать. - person Jon; 30.04.2014

Проще говоря...

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

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

person Community    schedule 30.04.2014

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

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

Получает Dispatcher для выполняемого в данный момент потока и создает новый Dispatcher, если он еще не связан с потоком.


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

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

person H.B.    schedule 04.05.2012