rco
rco

Reputation: 355

Execute method on another thread with ToObservable

I have a problem running a method (based on ToObservable) on a non UI-thread in a WPF-application.

For example I have this method:

    public IObservable<ViewModel> Get()
    {
        IEnumerable<ViewModel> vms = _repository.Get();

        Thread.Sleep(2000);

        return vms.ToObservable();
    }

I use this method in the ViewModel:

  manager.Get()
         .ObserveOnDispatcher()
         .SubscribeOn(new NewThreadScheduler())
         .Subscribe(result =>
                    {
                        Data.Add(result);
                    });

The problem is that method Get is executed on the UI/Main thread but I need to run this method on a non-UI thread.

Upvotes: 0

Views: 428

Answers (2)

Enigmativity
Enigmativity

Reputation: 117027

I would suggest making the call to manager.Get() to be made inside Observable.Start and then just do a .Merge() to bring the IObservable<IObservable<ViewModel>> back to a IObservable<ViewModel>.

Try this:

Observable
    .Start(() => manager.Get(), Scheduler.Default)
    .Merge()
    .ObserveOnDispatcher()
    .SubscribeOn(new NewThreadScheduler())
    .Subscribe(result =>
    {
        Data.Add(result);
    });

The .SubscribeOn(new NewThreadScheduler()) probably isn't necessary.

Upvotes: 1

Shlomo
Shlomo

Reputation: 14350

You have the right idea. However, in order to use the ObserveOn and SubscribeOn operators effectively, you need to have an observable source. In your example, it doesn't appear that you have that. Once you get that, you can do this:

IObservable<TAnything> source;

source
    .ObserveOn(Scheduler.ThreadPool)
    .SelectMany(_ => Get())
    .ObserveOn(DispatcherScheduler.Instance)
    .Subscribe(result =>
    {
        Data.Add(result);
    });

In your case, source will most likely be an observable generated from a button-click or some other event.

ObserveOn schedules code that follows it for the given scheduler. So in our case, the first ObserveOn call makes the code that follows happen on the ThreadPool (non-UI). The second ObserveOn makes the code happen on the dispatcher (UI).

SubscribeOn makes subscription-time code happen on a given scheduler. Since your code sample didn't have anything interesting happening at subscription-time, it makes sense to drop it.

Upvotes: 0

Related Questions