我目睹了onBackpressureBuffer的奇怪行为,我不确定它是否是有效行为或错误。
我有一个以特定速率发出项目的tcp调用(使用流和输入流,但仅用于某些信息)
除此之外,我已经创建了一个使用create的observable,每次准备就会发出一个项目。
让我们称之为消息()。
然后我这样做:
messages()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({//do some work});
我注意到使用分析工具很少抛出MissingBackPressureException,因此我已将onBackpressureBuffer添加到呼叫中。
如果我在observeOn
之后添加它:
messages()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.onBackpressureBuffer()
.subscribe({//do some work})
每个工作都很好,但这意味着只有在它进入UI主线程后它才会缓冲,所以我更喜欢它是这样的:
messages()
.onBackpressureBuffer()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({//do some work});
事情开始变得奇怪。
我注意到messages()
会一直发出项目,但在某些时候它们会停止发送给订阅者。
更确切地说,在完成了16项之后,显而易见的是缓冲区将开始持有物品而不会将它们向前传递。
一旦我用某种超时机制取消messages()
,它将导致messages()
发出onError()
并且缓冲区将立即发出它保存的所有项目(它们将是处理)。
我已经检查过是否订购了太多工作的用户错误,但事实并非如此,他已经完成了,但他仍然没有得到这些物品......
在request(n)
完成后,我还尝试在订阅者中使用onNext()
方法询问一个项目,但缓冲区没有表现出来。
我怀疑Main Android UI Thread的消息传递系统带有背压导致这种情况,但我无法解释原因。
有人可以解释为什么会这样吗?这是一个错误还是一个有效的行为? TNX!
答案 0 :(得分:5)
根据所描述的行为,不知道messages()
如何,这与this question
您没有尝试的解决方法是将.onBackpressureBuffer
置于 subscribeOn
和observeOn
之间。
messages()
.subscribeOn(Schedulers.io())
.onBackpressureBuffer() // <---------------------
.observeOn(AndroidSchedulers.mainThread())
.subscribe({//do some work});
答案 1 :(得分:1)
Question不同,但答案归结为同样的事情。
observeOn
构造函数的实现:OperatorObserveOn(Scheduler scheduler, boolean delayError, int bufferSize)
:
public OperatorObserveOn(Scheduler scheduler, boolean delayError, int bufferSize) {
this.scheduler = scheduler;
this.delayError = delayError;
this.bufferSize = (bufferSize > 0) ? bufferSize : RxRingBuffer.SIZE;
}
最后一行指向缓冲区大小。
Android上的buffer size为16。
解决方案只是将更大的缓冲区大小传递给observeOn(Scheduler scheduler, int bufferSize)
运算符:
messages()
.observeOn(AndroidSchedulers.mainThread(), {buffer_size})
小心不要过高的价值,因为Android的内存有限。