Rx.NET多订阅时DistinctUntilChanged重复触发问题如何解决
问题根因
重复执行的核心原因是你定义的mainSequence是冷Observable,这类Observable的特性是每新增一个独立订阅,就会从头启动整条管道的执行逻辑。
你当前代码里一共对mainSequence产生了3次独立订阅:
- 1次是全局错误处理的直接订阅
- 2次是循环内生成的
consecutive序列的间接订阅
3次订阅会各自独立执行从Observable.Range到SelectMany的全链路逻辑,你之前用的DistinctUntilChanged仅能在单个订阅的独立流内做去重,无法跨订阅共享执行结果,自然会重复调用DoSomethingAsync。
修复方案
你需要追加共享上游执行的响应式操作符,让所有订阅者共用同一条执行链路,避免重复触发逻辑。针对你的场景(后续会动态新增订阅者,且需要订阅者拿到最新的执行结果),使用Replay(1).AutoConnect()即可:
Replay(1)会缓存最新的1个执行结果,后续新增的订阅者可以直接拿到当前最新状态,不需要重新触发上游逻辑AutoConnect()会在第一个订阅者接入时自动连接上游,且连接一旦建立就不会因为订阅者退出而断开,保证全局逻辑只执行一次,直到条件变化才会触发下一次调用
只需要修改mainSequence的定义,在管道末尾追加这两个操作符:
var mainSequence = Observable.Range(0, 10) .Where(IsNumberOk) .DistinctUntilChanged(IsNumberOk) .SelectMany(DoSomethingAsync) .Replay(1) .AutoConnect();
修改后运行即可得到预期输出:
Working on 6 Working on 100 Working on 101
如果你的业务场景不需要给晚到的订阅者推送最新状态,且序列是长期存在的无限流(不会主动触发OnCompleted),也可以用Publish().RefCount()代替,二者的区别是RefCount()会在所有订阅者都退出时自动断开上游连接,不会长期占用资源。
内容的提问来源于stack exchange,提问作者ChristianMurschall
相关产品推荐
相关产品推荐

