gpt4 book ai didi

c# - Rx Throttle(...).ObserveOn(scheduler) 和 Throttle(..., scheduler) 的区别

转载 作者:行者123 更新时间:2023-11-30 13:56:24 27 4
gpt4 key购买 nike

我有以下代码:

IDisposable subscription = myObservable.Throttle(TimeSpan.FromMilliseconds(50), RxApp.MainThreadScheduler)
.Subscribe(_ => UpdateUi());

正如预期的那样,UpdateUi() 将始终在主线程上执行。当我将代码更改为

IDisposable subscription = myObservable.Throttle(TimeSpan.FromMilliseconds(50))
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(_ => UpdateUi());

UpdateUI() 将在后台线程中执行。

为什么 Throttle(...).ObserveOn(scheduler) 不等同于 Throttle(..., scheduler)

最佳答案

在代码的两个示例中,您提供的 UpdateUi 始终在 RxApp.MainThreadScheduler 指定的调度程序上调用。我可以肯定地说这一点,因为 ObserveOn 是一个装饰器,可确保在指定的调度程序上调用订阅者的 OnNext 处理程序。参见 here进行深入分析。

这么说,这有点令人费解。 RxApp.MainThreadScheduler 未引用正确的调度程序调度程序,或者 UpdateUi 正在从调度程序线程转换。前者并非史无前例 - 参见 https://github.com/reactiveui/ReactiveUI/issues/768其他人遇到过这个。我不知道那种情况下的问题是什么。也许@PaulBetts 可以权衡一下,或者您可以在 https://github.com/reactiveui/ 提出问题.无论如何,我会在这里仔细检查您的假设,因为我希望这是一个经过充分测试的领域。你有完整的复制品吗?

关于你的具体问题,Throttle(...).ObserveOn(scheduler)Throttle(..., scheduler) 的区别如下:

在第一种情况下,当指定 Throttle 时未指定调度程序,它将使用默认平台调度程序来引入运行其计时器所需的并发性 - 在 WPF 上,这将使用线程池线程。因此,所有节流都将在后台线程上完成,并且由于以下 ObserveOn,释放的事件只会传递给指定调度程序上的订阅者。

Throttle 指定调度程序的情况下,节流是在该调度程序上完成的 - 抑制的事件和已释放的事件都将在该调度程序上进行管理,订阅者也将在同一个调度程序上被调用.

因此无论哪种方式,UpdateUi 都会在 RxApp.MainThreadScheduler 上被调用。

在大多数情况下,您最好在调度程序上限制 ui 事件,因为如果只有一小部分事件要通过限制,则在后台线程上运行单独的计时器并为上下文切换付费通常成本更高。

所以,为了检查您没有遇到 RxApp.MainThreadScheduler 的问题,我会尝试通过其他方式明确指定调度程序或 SynchronizationContext。如何执行此操作将取决于您所在的平台 - ObserveOnDispatcher() 希望可用,或者使用合适的 ObserveOn 重载。如果导入了正确的 Rx 库,则可以选择控件、同步上下文和调度程序。

关于c# - Rx Throttle(...).ObserveOn(scheduler) 和 Throttle(..., scheduler) 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28816079/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com