我正在尝试为每个符号创建两个管道。每个符号将基于两个时间范围Buffer
进行数据,并在每个时间范围内执行DoCalc
。
priceChangedObservable = Observable.FromEvent<QuoteChangeEvent, IQuote>(handler =>
{
QuoteChangeEvent qHandler = (e) =>
{
handler(e);
};
return qHandler;
},
qHandler => bapi.MAPI.OnQuoteChange += qHandler,
qHandler => bapi.MAPI.OnQuoteChange -= qHandler
);
如果我执行以下操作:
var els = new EventLoopScheduler();
var dispatcher = new EventLoopScheduler();
var multiCastStream = Observable.Publish(priceChangedObservable);
int timeFrame = 60;
multiCastStream
.GroupBy(instrument => instrument.Symbol)
.SelectMany(q => q)
.Buffer(TimeSpan.FromSeconds(timeFrame))
.Where(messages => messages.Any())
.SubscribeOn(els)
.ObserveOn(dispatcher)
.Select((sr) => DoCalc(sr, timeFrame))
.Subscribe((en) => { if (null != en) Console.WriteLine(en); });
// Start the producer
multiCastStream.Connect();
一切正常。如果我注释上面的代码,并在multiCastStream.Connect()
语句之前添加第二个时间范围:
int secondTimeFrame = 300;
multiCastStream
.GroupBy(instrument => instrument.Symbol)
.SelectMany(q => q)
.Buffer(TimeSpan.FromSeconds(secondTimeFrame))
.Where(messages => messages.Any())
.SubscribeOn(els)
.ObserveOn(dispatcher)
.Select((sr) => DoCalc(sr, secondTimeFrame))
.Subscribe((en) => { if (null != en) Console.WriteLine(en); });
这也符合预期。但是,如果我同时运行两者代码,则会出现意外行为。
共享Hot Observables
时是否缺少一些基本知识?
编辑1
用Aron的答案修改代码后,我得到:
Number of quotes 1
60: 6/20/2019 10:53:26 PM=> M2KU9 Stats.
Number of quotes 1
300: 6/20/2019 10:53:26 PM=> M2KU9 Stats.
Number of quotes 40
60: 6/20/2019 10:54:26 PM=> MNQU9 Stats.
然后,没有其他统计信息被打印出来。
答案 0 :(得分:1)
一切正常,您的逻辑有缺陷。为了演示,我将绘制一个Rx Marble图
Quote -----------x--------------x-----------x-----------x--
Buffer1 | | | | | | | | | | | | | |
Buffer2 | | | | | | |
Where 1 ------------x---------------x-----------x-----------x
Where 2 ----------------------------------x-------x-----------
^Notice It seems like there should be an event on 2
But there wasn't?
相反,您可能要同步这些
var synchronizationSource = Observerable.Timer(TimeSpan.FromSeconds(1),TimeSpan.FromSeconds(1))
.Publish()
using(synchronizationSource.Connect())
{
IObservable<Stat> CreateTimeFrame(int seconds)
{
var bufferTimeFrame = synchronizationSource
.Where(i => i % seconds == 0);
return priceChangedObservable
.GroupBy(instrument => instrument.Symbol)
.SelectMany(q => q)
.Buffer(bufferTimeFrame)
.Where(messages => messages.Any())
.ObserveOn(dispatcher)
.Select((sr) => DoCalc(sr, timeFrame))
}
CreateTimeFrame(60)
.Subscribe((en) => { if (null != en) Console.WriteLine(en); });
CreateTimeFrame(300)
.Subscribe((en) => { if (null != en) Console.WriteLine(en); });
Thread.Sleep(100000);
}