如何从订阅向基于间隔的IObservable调度PropertyChanged事件

时间:2010-04-07 10:30:11

标签: c# silverlight multithreading system.reactive

当我尝试从通过Observable.Interval()创建的IObservable集合的订阅中引发PropertyChanged事件时,我收到'UnauthorizedAccesExpection - 无效的跨线程访问'异常。

凭借我有限的线程知识,我假设在事件想要在UI线程上发生时,某个其他线程上发生了间隔?对问题的解释非常有用。

代码看起来有点像:

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

任何解决方案?

编辑:

此代码正在从ViewModel而不是DependencyObject执行。

2 个答案:

答案 0 :(得分:2)

编辑:我将SubscribeOn与ObserveOn混淆了。我已经更新了我的答案

您可以通过将时间间隔放在调度程序线程上来解决问题:

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

或者,您可以使用ObserveOnDispatcher,但这会涉及跳线程,所以我建议不要使用它:

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

答案 1 :(得分:1)

使用: -

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

修改

由于您需要从ViewModel执行此操作,请参阅Jeff Wilcox撰写的此answer及其关于此主题的优秀博客:Property change notifications for multithreaded Silverlight applications