我在WPF应用程序中的非UI线程上运行方法(基于ToObservable
)时遇到问题。
例如我有这个方法:
public IObservable<ViewModel> Get()
{
IEnumerable<ViewModel> vms = _repository.Get();
Thread.Sleep(2000);
return vms.ToObservable();
}
我在ViewModel中使用此方法:
manager.Get()
.ObserveOnDispatcher()
.SubscribeOn(new NewThreadScheduler())
.Subscribe(result =>
{
Data.Add(result);
});
问题是方法Get
是在UI / Main线程上执行的,但我需要在非UI线程上运行此方法。
答案 0 :(得分:1)
我建议在manager.Get()
内拨打Observable.Start
,然后只需.Merge()
将IObservable<IObservable<ViewModel>>
带回IObservable<ViewModel>
试试这个:
Observable
.Start(() => manager.Get(), Scheduler.Default)
.Merge()
.ObserveOnDispatcher()
.SubscribeOn(new NewThreadScheduler())
.Subscribe(result =>
{
Data.Add(result);
});
.SubscribeOn(new NewThreadScheduler())
可能不是必需的。
答案 1 :(得分:0)
你有正确的想法。但是,为了有效地使用ObserveOn
和SubscribeOn
运算符,您需要有一个可观察的源。在您的示例中,您没有看到它。一旦你得到它,你可以这样做:
IObservable<TAnything> source;
source
.ObserveOn(Scheduler.ThreadPool)
.SelectMany(_ => Get())
.ObserveOn(DispatcherScheduler.Instance)
.Subscribe(result =>
{
Data.Add(result);
});
在您的情况下,source
很可能是通过按钮单击或其他事件生成的可观察对象。
ObserveOn
为给定的调度程序安排跟随它的代码。因此,在我们的示例中,第一个ObserveOn
调用使得后续代码发生在ThreadPool(非UI)上。第二个ObserveOn
使代码在调度程序(UI)上发生。
SubscribeOn
使订阅时代码在给定的调度程序上发生。由于您的代码示例在订阅时没有发生任何有趣的事情,因此删除它是有意义的。