我正在
无效的跨线程访问。
使用RX Throttle时
这是我的代码:
yObs.SubscribeOnDispatcher()
.DistinctUntilChanged()
.Throttle(TimeSpan.FromMilliseconds(33))
.SkipWhile(y => !_isDragging)
.Subscribe(y =>
{
// Exception when trying to access image
image.RenderTransform = new CompositeTransform() { TranslateY = -y };
_vm.UpdateContentDrag(y / image.ActualHeight * 100);
});
但如果我省略油门一切正常。
据我所知,Throttle使用线程池,因此OnNext不会发生在UI线程上。但是SubscribeOnDispatcher应该将它封送回UI线程。不应该吗?
答案 0 :(得分:12)
您对SubscribeOnDispatcher的理解不正确。首先,让我们区分两个* On运算符:
为了使您的示例正常工作,您还应该在查询中进一步使用ObserveOn运算符。我们的建议是在最终的订阅电话面前这样做。在查询中,并发性可以由诸如Throttle(其默认调度程序是线程池)的运算符引入。只有在您需要同步保证时,才会引入* On运算符。
Paul建议参数化Throttle调用也是一个很好的建议。如果您可以控制所引入的所有并发性,您可能希望这样做。但是,在许多情况下,您需要处理一个在同步要求方面不正常的IObservable序列,需要使用* On运算符。
答案 1 :(得分:4)
只需将该行更改为:
.Throttle(TimeSpan.FromMilliseconds(33), DispatcherScheduler.Instance)
无论如何它都更有效率(虽然33ms是一个非常短的时间跨度油门,达到了计时器分辨率)