.net - 使用 RX Throttle 时的跨线程异常

标签 .net c#-4.0 system.reactive reactive-programming

我正进入(状态

Invalid cross-thread access.



使用 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 ,一切正常。

据我了解,Throttle 使用线程池,因此 OnNext 不会发生在 UI 线程上。但是 SubscribeOnDispatcher 应该将其编码回 UI 线程。不应该吗?

最佳答案

您对 SubscribeOnDispatcher 的理解是错误的。首先,让我们区分两个 *On 运算符:

  • SubscribeOn* - 在指定的调度程序上运行(取消)订阅逻辑。很少使用,除非你玩 Observable.Create 等。
  • ObserveOn* - 在指定的调度程序上运行观察者消息(OnNext、OnError、OnCompleted)。主要用于运行传递给订阅的“事件处理程序”时的 UI 同步。

  • 为了让您的示例工作,您还应该在查询的下游继续使用 ObserveOn 运算符。我们的建议是在最后一次 Subscribe 调用之前这样做。在查询中,并发可以通过 Throttle(其默认调度程序是线程池)等操作符引入。只有在您需要同步保证时,才引入 *On 运算符。

    Paul 对 Throttle 调用进行参数化的建议也是一个很好的建议。在您可以控制引入的所有并发的情况下,您可能希望这样做。但是,在很多情况下,您收到的 IObservable 序列在同步要求方面表现不佳,需要使用 *On 运算符。

    关于.net - 使用 RX Throttle 时的跨线程异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8766812/

    相关文章:

    c# - 如何为多部分表单数据及其值形成WebRequest?

    c# - 以编程方式在 Web 浏览器控件 C# 中按 Tab

    system.reactive - Rx - 几个生产者/一个消费者

    .net - c# 环境中动态功能运行时的 future ?

    c# - 新年混沌HackerRank实践题-C#解法优化

    c# - 响应式(Reactive)编程中流之间的循环依赖

    c# - 你如何用响应式扩展扇出 observables

    c# - 为什么这些 Timer 事件会在不一致的时间引发?

    html - 子 ModalPopupExtender 不会以父 ModalPopupExtender 为中心

    c# - 是否可以通过命令提示符从 C# 运行 python 代码?