Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/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#_System.reactive - Fatal编程技术网

C# 系统无功-按频率动态切换

C# 系统无功-按频率动态切换,c#,system.reactive,C#,System.reactive,我有两个数据来源 让我们想象一下: 系统A以更高的频率提供更高质量的数据,例如。 1价格/1秒,但有时会出现故障,并且没有数据或数据 频率为1米/20秒 系统B提供较低频率的数据,例如1价格/10秒 是否有任何优雅的方法可以使用system.Responsive从系统A正常检索数据,但当feed中没有数据失败或速度减慢时,可以使用system B中的数据? 我想实现一种开关,当它比B快时,它将使用一个源。我不想混合源,所以我一次只能使用SystemA或SystemB 类价格源{ 公共IObser

我有两个数据来源

让我们想象一下:

系统A以更高的频率提供更高质量的数据,例如。 1价格/1秒,但有时会出现故障,并且没有数据或数据 频率为1米/20秒 系统B提供较低频率的数据,例如1价格/10秒 是否有任何优雅的方法可以使用system.Responsive从系统A正常检索数据,但当feed中没有数据失败或速度减慢时,可以使用system B中的数据? 我想实现一种开关,当它比B快时,它将使用一个源。我不想混合源,所以我一次只能使用SystemA或SystemB

类价格源{ 公共IObservable获取价格FeedIObservable价格Roma,IObservable价格Fromb { } private Price convertPrice from价格{//convert} private Price convertPrice fromb Price{//convert} }
有趣的问题。首先要做的是编写某种频率收集函数。可能是这样的:

public static IObservable<int> GetFrequency<T>(this IObservable<T> source, TimeSpan measuringFreq, TimeSpan lookback)
{
    return source.GetFrequency(measuringFreq, lookback, Scheduler.Default);
}

public static IObservable<int> GetFrequency<T>(this IObservable<T> source, TimeSpan measuringFreq, TimeSpan lookback, IScheduler scheduler)
{
    return source.Buffer(lookback, measuringFreq, scheduler)
        .Select(l => l.Count);
}
public static IObservable<T> MaintainFrequencyProper<T>(this IObservable<T> sourceA, IObservable<T> sourceB, TimeSpan measuringFreq, TimeSpan lookback, 
    IScheduler scheduler, int aAdvantage = 0)
{
    return sourceA.Publish(_sourceA => sourceB.Publish(_sourceB => 
        _sourceA.GetFrequency(measuringFreq, lookback, scheduler)
            .Zip(_sourceB.GetFrequency(measuringFreq, lookback, scheduler), (a, b) => a + aAdvantage - b)
            .Select(freqDifference => freqDifference < 0 ? _sourceB : _sourceA)
            .StartWith(_sourceA)
            .Switch()

    ))
}
nums是一个可观察的对象,它应该平均每半秒生成一条消息,并在0到1秒之间随机选择一个持续时间。freq每秒生成一个值,该值返回在过去5秒内生成的消息数nums,平均值应为10。在我的机器上的最新运行中,我得到以下信息:

11
11
12
10
12
11
9
9
10
9
8
...
一旦我们有了获得频率的方法,你需要编写一个函数来合成两个相似类型的观测值,根据频率进行切换。我写道:

public static IObservable<T> MaintainFrequencyImproper<T>(this IObservable<T> sourceA, IObservable<T> sourceB, TimeSpan measuringFreq, TimeSpan lookback, IScheduler scheduler, int aAdvantage = 0)
{
    var aFreq = sourceA.GetFrequency(measuringFreq, lookback, scheduler);
    var bFreq = sourceB.GetFrequency(measuringFreq, lookback, scheduler);

    var toReturn = aFreq.Zip(bFreq, (a, b) => a + aAdvantage - b)
        .Select(freqDifference => freqDifference < 0 ? sourceB : sourceA)   //If advantage is 0, and a & b both popped out 5 messages in the last second, then A wins
        .StartWith(sourceA)
        .Switch();

    return toReturn;
}

我希望这有帮助。在如何将其融入代码方面,您没有留下太多东西。如果您需要,请附上。

Nice。用CombineTest代替Zip怎么样?我认为另一个方面是,应该比较慢的频率dropCombineTest更早检测超时,这将为组合两个频率观测值带来竞争条件问题。因为它们基本上在同一个计时器上,所以我看不出有什么意义。至于超时,如果您将测量频率设置为短于超时持续时间,它将比超时检测系统更快,而不是更慢。更新:我意识到GetFrequency可以使用缓冲区而不是更简单的扫描。我相应地修改了代码。
public static IObservable<T> MaintainFrequencyProper<T>(this IObservable<T> sourceA, IObservable<T> sourceB, TimeSpan measuringFreq, TimeSpan lookback, 
    IScheduler scheduler, int aAdvantage = 0)
{
    return sourceA.Publish(_sourceA => sourceB.Publish(_sourceB => 
        _sourceA.GetFrequency(measuringFreq, lookback, scheduler)
            .Zip(_sourceB.GetFrequency(measuringFreq, lookback, scheduler), (a, b) => a + aAdvantage - b)
            .Select(freqDifference => freqDifference < 0 ? _sourceB : _sourceA)
            .StartWith(_sourceA)
            .Switch()

    ))
}