views:

241

answers:

2

I'm getting an 'UnauthorizedAccesExpection - Invalid cross-thread access' exception when I try to raise a PropertyChanged event from within a subscription to an IObservable collection created through Observable.Interval().

With my limited threading knowledge I'm assuming that the interval is happening on some other thread while the event wants to happen on the UI thread??? An explanation of the problem would be very useful.

The code looks a little like:

var subscriber = Observable.Interval(TimeSpan.FromSeconds(1))
                .Subscribe(x =>
                {
                    Prop = x; // setting property raises a PropertyChanged event
                });

Any solutions?

Edit:

This code is being executed from a ViewModel not a DependencyObject.

+1  A: 

Use:-

var subscriber = Observable.Interval(TimeSpan.FromSeconds(1))
            .Subscribe(x =>
            {
                Dispatcher.BeginInvoke(() => Prop = x);
            });

Edit

Since you need to do this from the ViewModel see this answer by Jeff Wilcox and his excellent blog on the subject: Property change notifications for multithreaded Silverlight applications.

AnthonyWJones
This is being called from a ViewModel not a DependencyObject so I don't have a Dispatcher property.
James Hay
+2  A: 

Edit: I was confusing SubscribeOn with ObserveOn. I've updated my answer

You can solve your problem by putting your interval on the dispatcher thread:

var subscriber = Observable.Interval(TimeSpan.FromSeconds(1), Scheduler.Dispatcher) 
                .Subscribe(x => 
                { 
                    Prop = x; // setting property raises a PropertyChanged event 
                }); 

Alternatively, you could be able to use ObserveOnDispatcher but that would involve jumping threads so I'd recommend against it:

var subscriber = Observable.Interval(TimeSpan.FromSeconds(1)) 
                .ObserveOnDispatcher()
                .Subscribe(x => 
                { 
                    Prop = x; // setting property raises a PropertyChanged event 
                }); 
Richard Szalay