当前位置:  开发笔记 > 编程语言 > 正文

WPF Dispatcher是多线程问题的解决方案吗?

如何解决《WPFDispatcher是多线程问题的解决方案吗?》经验,为你挑选了1个好方法。

我对在代码中使用锁有一种非常糟糕的感觉,但现在WindowBase的Dispatcher存在,我想在任何地方使用它.

例如,我使用多线程单例WCF服务,它在PRISM的EventAggregator上发布事件,有效负载是不可变的(它只是数据),每个带调度程序的线程都可以优雅地检索事件,在自己的调度程序中完成死锁.(不仅是UI线程,还有具有数据库调用的线程,具有服务调用的线程,具有慢速调用的日志或其他线程的线程,因为我不想冻结UI).

但我的问题是这个Dispatcher与WPF结合在一起,所以当我到处使用它时我感到有点内疚,我觉得调度程序不是为我的用例而创建的.

是否存在另一个不与WPF结合的Dispatcher实现?或者可以滥用它?

谢谢,

更新

Paul Stovell给我的解决方案是创建一个接口IDispatcher,以及一个Wpf Dispatcher的适配器,所以这将更容易测试!这个解决方案对我有好处,因为我重构了我的测试,我现在可以在我的测试中使用SynchronousDispatcherAdapter(感谢它,我不必在我的测试中使用WPF的Dispatcher).

使用Dispatcher而不是BackgroundWorker是有道理的,因为我使用的是多发布者/订阅者模式(使用PRISM),并且由于Dispatcher,每个事件处理程序都会在订阅它们的事件上调用.这意味着可能发生多线程问题的唯一一点是我的事件的有效负载(我使他成为不可变的).

我的不同线程不直接在它们之间进行通信,它们只能发布和订阅事件.因此,数据库调用,日志调用,服务调用,UI调用在不同的线程上运行,彼此不了解(他们只知道他们订阅和发布的事件).

当我从UI访问存储库时,后台工作人员会有意义.

但是我希望在不使用BackgroundWorker的情况下找到一个设计,因为我更喜欢使用这个订阅者/发布者模式(我认为它使我的代码更具可读性)



1> Paul Stovell..:

使用Dispatcher(或BackgroundWorker)的主要问题是它很难测试,除非您的测试工具实际上有一个UI线程.

解决方案1

使用SynchronizationContext.它提供了在UI线程上调用并在Windows或WPF中工作的相同功能.也可以测试它.

解决方案2

将调度员视为另一种服务.当您使用PRISM时,您熟悉服务和IOC.以下是如何使用此类服务​​:

// 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容器中注册它们,它们可用于UI和其他服务.

推荐阅读
夏晶阳--艺术
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有