【问题标题】:How to prevent circular reference in MVVM when using DispatcherObject.Dispatcher使用 DispatcherObject.Dispatcher 时如何防止 MVVM 中的循环引用
【发布时间】:2012-05-03 19:28:24
【问题描述】:

下面的代码非常简化。我正在尝试抽象一个调度程序上下文,以便我的视图模型可以同步只能在 GUI 线程上引发的事件。

此模式中有一个循环引用。有没有其他方法可以创建DispatcherObject?我做错了吗?

我读过其他类似的问题,但答案似乎都涉及到ViewModel 中对DispatcherObject 的引用。这是一个可以接受循环引用的地方吗?

class ViewModel {
    public DispatcherObject Dispatcher { get; set; }
}

class ModelView : UserControl {

    ModelView() {
        InitializeComponent();
        DataContext = new ViewModel { Dispatcher = this };
    }
}

【问题讨论】:

    标签: .net wpf mvvm dispatcher circular-reference


    【解决方案1】:

    一般来说,循环引用是您要避免的。这里有两种选择:

    1。静态抓取调度器

    快速而肮脏的方法。很容易做到,几乎所有时间都可以正常工作,但与其他任何静态完成的事情一样,它不适合可测试性(这可能是也可能不是问题)。在您的 WPF 应用程序具有多个 UI 线程的极少数情况下,您将无法盲目地使用这种方法。

    WPF:var dispatcher = Application.Current.Dispatcher;

    银光:var dispatcher = Deployment.Current.Dispatcher;

    2。使调度程序成为 ViewModel 的依赖项

    适当地配置您的依赖注入容器,并让 Dispatcher 成为那些需要访问它的 ViewModel 的依赖。这种方法比较麻烦,但它允许您使用多个 UI 线程,是可测试的,并且通常具有使用 DI 做事的所有常见优点/缺点。

    【讨论】:

    • 谢谢。我采用了一种将两者结合起来的方法。 ViewModel 抓取一个静态定义的 Dispatcher,该静态实例可以由应用程序、单元测试等进行更新。
    • 我还问了另一个关于Application.Current.Dispatcher和Dispatcher.CurrentDispatcher的区别的问题:stackoverflow.com/questions/10448987/…
    【解决方案2】:

    无需从控件中获取特定的调度程序。您可以直接通过 Deployment 进行调度,即 Deployment.Current.Dispatcher.BeginInvoke(()=>something)。

    我通常不提供调度程序对象,而是提供一个动作委托。然后,您可以通过只执行操作来测试而不跳线程,而在生产中它可以在 Dispatcher 上调用。

    【讨论】:

    • 感谢您的回复,但部署类似乎仅限 Silverlight。
    • 这让我想到了 WPF 中可用的类似概念:Dispatcher.CurrentDispatcher。 msdn.microsoft.com/en-us/library/…
    【解决方案3】:

    当您真正需要调用的是调度程序本身时,为什么还要保留对 DispatcherObject 的引用?

    class ViewModel {
        public Dispatcher Dispatcher { get; set; } }
    
    class ModelView : UserControl {
    
        ModelView() {
            InitializeComponent();
            DataContext = new ViewModel { Dispatcher = Dispatcher };
        } }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-12
      • 2011-03-18
      • 1970-01-01
      • 1970-01-01
      • 2016-07-13
      • 1970-01-01
      • 2013-01-07
      相关资源
      最近更新 更多