Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 有热可观察到的问题_C#_Observable_System.reactive - Fatal编程技术网

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);
 }