我想使用Rx Buffer功能:
var source = new Subject<Price>();
var buffer = source
.Buffer(TimeSpan.FromSeconds(30), 5)
.Where(p => p.Any());
这意味着当缓冲区达到自上次发射后5或30秒的大小时发生(发布给订阅者)。
但我需要能够按需发出 - 例如当我收到高优先级序列项时。然后我想将它添加到observable(source.OnNext()
)并以某种方式强制它发出(这意味着返回缓冲区中的所有元素并清除它)。
我知道我可以添加以下代码:
var flusher = new Subject<Price>();
var closing = flusher.Select(x => new List<Price> {x});
var query = buffer.Merge(closing).Subscribe(something);
并调用flusher.OnNext(highPriorityItem),我将发出它。
但在这种情况下,我有两个独立的序列,有两个不同的发射。当缓冲区已满或特定项目按顺序出现时,我需要一个发射。
Force flush count-type Observable.Buffer c#和Force flush to Observable.Buffer c#似乎不适合我
答案 0 :(得分:4)
我认为decPL在这里有基本的想法,但他的解决方案并不稳定。根据{{1}}观察者的调度程序,即使按正确的顺序订阅,您也可能获得不可预测的结果。那是因为input
有多个独立订阅。您需要通过input
调用全部推送,以确保只有一个订阅。
此外,它还需要一种在处理订阅时进行清理的方法。所以它还需要通过.Publish(...)
调用。
以下是:
.Create(...)
答案 1 :(得分:2)
尝试以下内容:
var input = new Subject<Price>(); //your input observable
var flush = new Subject<long>(); //used to manually flush the 'buffer' for important prices
var timeBuffer
= Observable.Timer(TimeSpan.FromSeconds(10)); //controls the time-based part of 'buffer'
var sizeBuffer = input.Buffer(5).Select(l => 0L); //controls the size-based part of 'buffer'
var bufferedInput = input.Window(()=>Observable.Merge(timeBuffer, sizeBuffer, flush))
.SelectMany(w => w.ToList())
.Subscribe(w => DO_SOMETHING_WITH_PRICES(w));
//Flush on important price (NOTE - order of the two subscriptions matter)
input.Where(p => p.IS_IMPORTANT).Subscribe(p => flush.OnNext(0L));