在另一个线程上使用ToObservable执行方法

本文关键字:ToObservable 执行 方法 另一个 线程 | 更新日期: 2023-09-27 18:09:02

我在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/主线程上执行,但我需要在非UI线程上运行此方法。

在另一个线程上使用ToObservable执行方法

我建议在Observable.Start内部调用manager.Get(),然后只做.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())可能不是必需的。

你的想法是对的。然而,为了有效地使用ObserveOnSubscribeOn操作符,您需要有一个可观察的源。在你的例子中,你似乎没有这个。一旦你得到了,你可以这样做:

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使订阅时代码发生在给定的调度程序上。由于您的代码示例在订阅时没有发生任何有趣的事情,因此删除它是有意义的。