C# 有热可观察到的问题
我试图为每个符号创建两个管道。每个符号将基于两个时间段C# 有热可观察到的问题,c#,observable,system.reactive,C#,Observable,System.reactive,我试图为每个符号创建两个管道。每个符号将基于两个时间段缓冲数据,并在每个时间段上执行DoCalc priceChangedObservable = Observable.FromEvent<QuoteChangeEvent, IQuote>(handler => { QuoteChangeEvent qHandler = (e) => { handler(e); }; ret
缓冲
数据,并在每个时间段上执行DoCalc
priceChangedObservable = Observable.FromEvent<QuoteChangeEvent, IQuote>(handler =>
{
QuoteChangeEvent qHandler = (e) =>
{
handler(e);
};
return qHandler;
},
qHandler => bapi.MAPI.OnQuoteChange += qHandler,
qHandler => bapi.MAPI.OnQuoteChange -= qHandler
);
一切都按照我的预期进行。如果我注释掉上述代码,并在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); });
这也和预期的一样有效。但是,如果我运行了两个代码,我会得到意外的行为
在分享热观测时,我是否缺少一些基本的东西
编辑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.
然后,就不会打印其他统计数据了。一切正常,您的逻辑有缺陷。为了演示,我将绘制一个Rx大理石图
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);
}
var synchronizationSource=observer.Timer(TimeSpan.FromSeconds(1),TimeSpan.FromSeconds(1))
.Publish()
使用(synchronizationSource.Connect())
{
IObservable CreateTimeFrame(整数秒)
{
var bufferTimeFrame=synchronizationSource
。其中(i=>i%秒==0);
返回价格可更改可服务
.GroupBy(仪表=>instrument.Symbol)
.SelectMany(q=>q)
.Buffer(缓冲时间段)
.Where(messages=>messages.Any())
.ObserveOn(调度员)
.选择((sr)=>DoCalc(sr,时间范围))
}
创建时间框架(60)
.Subscribe((en)=>{if(null!=en)Console.WriteLine(en);});
创建时间框架(300)
.Subscribe((en)=>{if(null!=en)Console.WriteLine(en);});
睡眠(100000);
}
是否有任何理由需要可观察的.Publish()
?如果我读对了,你应该能够完全摆脱.Publish
,你也可以摆脱.SubscribeOn
。那么发布就是将事件作为一个[热]可观察的对象共享(多播)。还有,你的“意外行为”是什么。唯一可能出乎意料的是,缓冲窗口的边界不匹配,因此DoCalc
边界不匹配。出乎意料的意思是,有时我得到的结果是一个,而不是另一个,即使必须有一个,因为DoCalc所做的就是收集我知道发生在我眼前的引用的统计数据。你为什么认为你需要发布?发布不是“多播”。这样,多个订阅服务器(下游)可以共享一个订阅(bapi.MAPI.OnQuoteChange+=qHandler
)。您应该能够在bapi.MAPI.OnQuoteChange
上拥有多个EventHandler(以及订阅)。也许我没有解释我所期望的效果。我想每分钟和每五分钟收集每个符号的引号,并计算每个符号的统计数据。我试过你给我的密码,但没用。请参阅原始帖子中的编辑1。使用您的代码,我能够使其正常工作。我不得不稍微修改一下。我稍后会发布。
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);
}