phil
phil

Reputation: 638

How to Marshal to UI thread correctly in ReactiveUI 6.0

I have an Observable like this:

var posChangeObs =
            Observable.Publish<DisplayPositionModel>(
                Observable
                    .FromEventPattern<EventHandler<PositionEventArgs>, PositionEventArgs>(h => cine.PositionChange += h,
                                                                                          h => cine.PositionChange -= h,
                                                                                          RxApp.MainThreadScheduler)
                    .Select(x => new DisplayPositionModel(cine.ToDisplayPosition(x.EventArgs.Position), x.EventArgs.LinearFrameIndex)),
                    new DisplayPositionModel(cine.ToDisplayPosition(cine.CurrentCinePosition), cine.CurrentLinearCinePosition));

The event this tracks will always occur on a different thread. I pass this Observable to a lot of different view models. In some view models the eventArgs are set to a property using ToProperty. In others I just Subscribe and DoStuff(TM).

What I want to know is how to ensure that these are always marshaled to the UI thread. I have tried adding ObserveOn(RxApp.Main...) on all of the ToProperty and Subscribe calls, but that did not work.

Here is an example of how I am using ToProperty right now and getting cross thread exception:

posChangeObs.ToProperty(this, x => x.CurrentPosition, out _CurrentPosition);

and here is an example Subscription:

posChangeObs
            .Select(x => x.LinearFrameIndex)
            .Subscribe(x => this.CurrentLinearFrameIndex = x,
            e =>
            {
                throw e;
            });

Upvotes: 2

Views: 785

Answers (1)

phil
phil

Reputation: 638

The answer was to add the ObserveOn(RxApp.MainThreadScheduler) to the return of FromEventPattern. Like this

var posChangeObs = Observable.Publish<Position>(
    Observable.FromEventPattern<EventHandler<PositionEventArgs>,PositionEventArgs>(h => x.PositionChange += h, h => x.PositionChange -= h)
       .ObserveOn(RxApp.MainThreadScheduler)
       .Select(x => ...));

Upvotes: 2

Related Questions