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

时间:2016-09-26 11:27:28

标签: c# multithreading system.reactive observable

我在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线程上运行此方法。

2 个答案:

答案 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)

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