C# 系统无功-按频率动态切换
我有两个数据来源 让我们想象一下: 系统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} }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
有趣的问题。首先要做的是编写某种频率收集函数。可能是这样的:
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()
))
}