我应该使用dispatcher.Invoke(...)还是ObserveOn(调度程序)?

时间:2014-07-22 15:15:02

标签: c# system.reactive reactiveui

我已经获得了一些代码来处理调度程序在其构造函数中传递给视图模型的位置。我现在想知道当我想在UI线程上执行某些操作时是否应该使用ObserveOn(dispatcher)dispatcher.Invoke(...)

例如,我可以这样做:

this.WhenAny(me => me.SomeValue, _ => Unit.Default)
.ObserveOn(dispatcher)
.Subscribe(_ => SomeMethod());

...

private void SomeMethod()
{
    //do some stuff
}

或者我可以这样做:

this.WhenAny(me => me.SomeValue, _ => Unit.Default)
.Subscribe(_ => SomeMethod());

这意味着我可以这样做:

private void SomeMethod()
{
    dispatcher.Invoke(new Action(() =>{//do some stuff});
}

两者之间有什么重大差异吗?

我担心的是,如果我想在代码中的某个其他部分调用SomeMethod(),而SomeValue不会触发它,该怎么办?我需要做dispatcher.invoke(new Action(() => someMethod()));,这让我觉得使用dispatcher.Invoke(...)里面的SomeMethod是最好的选择。

这是好事还是坏事?在那一分钟,我平均使用两种技术。我打算转到其中一个,但想先知道正确的方法。

2 个答案:

答案 0 :(得分:5)

我会看到是否可以为IScheduler提供DispatcherScheduler的实例。通过这种方式,我可以使用TestScheduler测试我的代码,而无需进入调度程序和推帧等等。一旦有了IScheduler的实例,那么你可以使用它来ObserveOn(dispatcherScheduler)

我同意@mclaassen你应该知道你所在的调度程序/线程,因此你是否需要调度/调用。因此,例如,如果您正在观察INotifyPropertyChanged事件,那么您将在调度员上,因此无需发送。如果您正在接收来自网络呼叫或繁重计算的响应,那么您可能在另一个线程上,因此您应该安排/调度以返回调度员。费用

Rx中的标准模式是要么不进行调度,因为你已经使用了正确的线程:

//this is a ViewModel, and property changes occur on the dispatcher
this.WhenAny(
    vm => vm.PropertyA, 
    vm => vm.PropertyB, 
    _ => Unit.Default)
.Subscribe(_ => SomeMethod());

或者,应用SubscribeOn / ObserveOn模式来下载当前线程,执行工作,然后在原始线程上接收结果。

myRepo.GetDataFromNetwork()
    .SubscribeOn(taskPoolScheduler)
    .ObserveOn(dispatcherScheduler)
    .Subscribe(_ => SomeMethod());

答案 1 :(得分:3)

功能上没有区别。但是,我会使用ObserveOn(dispatcher)并保留SomeMethod()。您可能稍后也会从UI线程调用SomeMethod(),在这种情况下,调度将是不必要的。我会说调用代码应该负责知道它是否在UI线程上运行,因此是否需要调度。