Подтвердить что ты не робот

Является ли диспетчер WPF решением проблем с несколькими потоками?

У меня очень плохое чувство об использовании блокировки в моем коде, но теперь Диспетчер WindowBase существует, и я хочу использовать его везде.

Например, я использую многопользовательскую службу singleton WCF, которая публикует события в EventAggregator PRISM, полезная нагрузка неизменна (это всего лишь данные), и каждый поток с диспетчером может изящно извлекать событие, независимо от тупика в своем диспетчере, (Не только поток пользовательского интерфейса, но также потоки с вызовами базы данных, потоки с вызовом служб, потоки, которые регистрируются или другие потоки с медленными вызовами, потому что я не хочу замораживать пользовательский интерфейс).

Но моя проблема заключается в том, что этот диспетчер связан с WPF, поэтому я чувствую себя немного виноватым, когда использую его везде, я чувствую, что диспетчер не был создан для моего использования.

Существует ли еще одна реализация диспетчера, не связанная с WPF? или что ОК, чтобы злоупотреблять им?

Спасибо,

Обновление

Решение, которое Пол Стовелл дает мне, это создать интерфейс IDispatcher и адаптер для диспетчера Wpf, так что это будет легче протестировать! Это решение было полезно для меня, потому что я реорганизовал свои тесты, и теперь я могу использовать SynchronousDispatcherAdapter в своих тестах (благодаря этому мне не нужно использовать диспетчер WPF в моих тестах).

Использование диспетчера вместо BackgroundWorker имеет смысл, потому что я использую шаблон нескольких издателей/подписчиков (с PRISM), и благодаря диспетчеру каждый обработчик событий вызывается в потоках, которые подписывают их на событие. Это означает, что единственная точка, в которой может возникнуть проблема с несколькими потоками, - это полезная нагрузка моего события (я сделал его неизменным).

Мои разные потоки не связываются напрямую между ними, они могут просто публиковать и подписываться на событие. Таким образом, вызовы базы данных, вызовы журналов, вызовы служб, вызовы пользовательского интерфейса выполняются на разных потоках и не знают друг о друге (они знают только о событиях, которые они подписывают и публикуют).

Фоновый работник будет иметь смысл, когда я сделаю некоторые вызовы из моего интерфейса в репозиторий.

Но я надеюсь найти дизайн без использования BackgroundWorker, потому что я предпочитаю использовать этот шаблон подписчика/издателя (я думаю, что он делает мой код более удобочитаемым)

4b9b3361

Ответ 1

Основная проблема с использованием диспетчера (или BackgroundWorker) заключается в том, что его трудно тестировать, если у вашего тестового жгута фактически нет потока пользовательского интерфейса.

Решение 1

Используйте SynchronizationContext. Он обеспечивает ту же самую способность ссылаться на поток пользовательского интерфейса и работает в Windows или WPF. Тестирование также возможно.

Решение 2

Подумайте, что диспетчер будет просто еще одной услугой. Когда вы используете PRISM, вы знакомы с услугами и МОК. Вот как можно использовать такую ​​услугу:

// Not a UI component
public class MyDomainService : IMyDomainService
{
   private readonly IDispatcher _dispatcher;

   public MyDomainService(IDispatcher dispatcher) 
   {
      _dispatcher = dispatcher;
   }

   private void GotResultFromBackgroundThread()
   {
       _dispatcher.Dispatch(() => DoStuffOnForegroundThread());
   }
}

Это позволяет вам заменить в разных реализациях вашей платформы/тестирования.

Вот пример IDispatcher, реализация WPF и . Вы зарегистрировали бы их в своем контейнере IOC, как и любую другую услугу, и они доступны как для пользовательского интерфейса, так и для других служб.

Ответ 2

да и нет.. его вещь для рендеринга... ничтожная вещь сама по себе..

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

Вам все равно придется самостоятельно обрабатывать любые темы, которые вы начинаете сами.

Отметьте этот для получения информации о: Многопоточное программирование с асинхронным шаблоном на основе событий

Лично я использую Background Worker для моих потребностей в потоке.

Лучшие практики здесь.