WPF / threading: статический диспетчер vs диспетчер на элементе управления? - PullRequest
9 голосов
/ 07 января 2011

Я немного запутался с точки зрения диспетчера. Скажем, я в фоновом потоке выполняю какую-то долгую операцию. Я хотел бы обновить поток пользовательского интерфейса, я понимаю, я делаю это через диспетчер. У меня вопрос, могу ли я вызвать диспетчер статически, как: Dispatcher.BeginInvoke (mywork) ... Или на элемент управления, который я хочу обновить: mytextbox.Dispatcher.BeginInvoke (mywork)

Ответы [ 3 ]

15 голосов
/ 23 февраля 2011

Стоит отметить, что вызов Dispatcher.BeginInvoke не статический вызов: это неявный this.Dispatcher.BeginInvoke. Если вы можете использовать этот вызов, вы, вероятно, уже пишете свой код из элемента управления или окна. В этом случае вы можете , вероятно, безопасно звонить, поскольку в большинстве случаев для каждого приложения будет один поток пользовательского интерфейса.

Фактический статический вызов будет Dispatcher.CurrentDispatcher.BeginInvoke, что означает , а не то, что вы хотите назвать (см. Мой комментарий к ответу Хасана Хана, почему).

РЕДАКТИРОВАТЬ: Вызов Application.Current.Dispatcher это не плохо. (И, для ясности, это свойство экземпляра, а не статическое - вызывается для статического / одноэлементного экземпляра Application.) Это свойство возвращает Dispatcher для потока, с которым было создано приложение, и обычно это поток что пользовательский интерфейс создан на aswell - поэтому Application.Current.Dispatcher возвращает тот же Диспетчер, что и myWindow.Dispatcher.

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

1 голос
/ 23 февраля 2011

Сначала я думаю, что важно понимать, что Dispatcher не предназначен для обработки больших фоновых операций.Он предназначен для постановки в очередь в потоке пользовательского интерфейса объекта.Вот полезная статья MSDN о модели потоков .NET и Dispatcher:

Сказать, что стандартным способом реализации метода Dispatcher.BeginInvoke было бы вызвать его для элемента управления:

startStopButton.Dispatcher.BeginInvoke(
    DispatcherPriority.Normal, new NextPrimeDelegate(CheckNextNumber)
);

Надеюсь, это поможет!

0 голосов
/ 21 марта 2014

В то время как в большинстве случаев используется либо DispatcherObject.Dispatcher (все объекты зависимостей и элементы управления наследуются от DispatcherObject, среди прочего), либо Application.Current.Dispatcher - это правильно, так как обычно есть только один пользовательский интерфейсПоток, может быть несколько потоков пользовательского интерфейса, и разные окна могут использовать разные диспетчеры.В этом случае важно обновить элемент управления, используя его диспетчер.Он хранится в свойстве Dispatcher (унаследованном от DispatcherObject), в любом другом элементе управления в этом окне и в самом окне.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...