How can I dispatch an PropertyChanged event from a subscription to an Interval based IObservable
-
25-09-2019 - |
Question
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.
Solution
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
});
OTHER TIPS
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.