0

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

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

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

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

class ModelView : UserControl {

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

3 回答 3

3

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

1.静态抓取dispatcher

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

WPF:var dispatcher = Application.Current.Dispatcher;

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

2.使dispatcher成为ViewModel的依赖

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

于 2012-05-04T07:55:06.047 回答
1

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

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

于 2012-05-03T21:11:13.043 回答
1

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

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

class ModelView : UserControl {

    ModelView() {
        InitializeComponent();
        DataContext = new ViewModel { Dispatcher = Dispatcher };
    } }
于 2012-05-04T08:43:45.603 回答