C# Rx扩展将持续生成事件N秒?
什么是正确的Rx扩展方法(在.NET中)来保持生成事件N秒 通过“持续生成N秒事件”,我的意思是它将在循环中从DateTime.Now到DateTime.Now+TimeSpan.FromSeconds(N)持续生成事件 我正在研究遗传算法,它将产生大量的假设,并将最成功的假设传播给下一代。需要以优雅的方式约束这家伙 稍后添加: 事实上,我意识到我需要做的是拉而不是推,于是我想出了这样的办法:C# Rx扩展将持续生成事件N秒?,c#,.net,system.reactive,C#,.net,System.reactive,什么是正确的Rx扩展方法(在.NET中)来保持生成事件N秒 通过“持续生成N秒事件”,我的意思是它将在循环中从DateTime.Now到DateTime.Now+TimeSpan.FromSeconds(N)持续生成事件 我正在研究遗传算法,它将产生大量的假设,并将最成功的假设传播给下一代。需要以优雅的方式约束这家伙 稍后添加: 事实上,我意识到我需要做的是拉而不是推,于是我想出了这样的办法: public static class IEnumerableExtensions { pub
public static class IEnumerableExtensions
{
public static IEnumerable<T> Pull<T>(this IEnumerable<T> enumerable, int? times = null)
{
if (times == null)
return enumerable.ToArray();
else
return enumerable.Take(times.Value).ToArray();
}
public static IEnumerable<T> Pull<T>(this IEnumerable<T> enumerable, TimeSpan timeout, int? times = null)
{
var start = DateTime.Now;
if (times != null) enumerable = enumerable.Take(times.Value);
using (var iterator = enumerable.GetEnumerator())
{
while (DateTime.Now < start + timeout && iterator.MoveNext())
yield return iterator.Current;
}
}
}
可能有一种更干净的方法,但您可以使用:
// This will generate events repeatedly
var interval = Observable.Interval(...);
// This will generate one event in N seconds
var timer = Observable.Timer(TimeSpan.FromSeconds(N));
// This will combine the two, so that the interval stops when the timer
// fires
var joined = interval.TakeUntil(timer);
我已经很久没有做任何Rx了,因此如果这是错误的,我很抱歉-但值得一试…可能有一种更干净的方法,但您可以使用:
// This will generate events repeatedly
var interval = Observable.Interval(...);
// This will generate one event in N seconds
var timer = Observable.Timer(TimeSpan.FromSeconds(N));
// This will combine the two, so that the interval stops when the timer
// fires
var joined = interval.TakeUntil(timer);
我已经很久没有做任何Rx了,所以如果这是错误的,我很抱歉-但值得一试…Jon的帖子非常贴切,但是我注意到你的编辑,你建议你创建自己的扩展方法来做这件事。我想如果你只使用内置的操作符会更好
//LinqPad sample
void Main()
{
var interval = Observable.Interval(TimeSpan.FromMilliseconds(250));
var maxTime = Observable.Timer(TimeSpan.FromSeconds(10));
IEnumerable<int> lazySource = Enumerable.Range(0, 100);
lazySource.ToObservable()
.Zip(interval, (val, tick)=>val)
.TakeUntil(maxTime)
.Dump();
}
//LinqPad示例
void Main()
{
var interval=可观测的时间间隔(TimeSpan.From毫秒(250));
var maxTime=可观测计时器(时间跨度从秒(10))开始);
IEnumerable lazySource=可枚举的范围(0100);
lazySource.ToObservable()
.Zip(间隔,(val,tick)=>val)
.TakeUntil(最大时间)
.Dump();
}
*也就是说,其他开发人员很容易维护和理解Jon的帖子,但是我注意到你的编辑建议你创建自己的扩展方法来实现这一点。我想如果你只使用内置的操作符会更好
//LinqPad sample
void Main()
{
var interval = Observable.Interval(TimeSpan.FromMilliseconds(250));
var maxTime = Observable.Timer(TimeSpan.FromSeconds(10));
IEnumerable<int> lazySource = Enumerable.Range(0, 100);
lazySource.ToObservable()
.Zip(interval, (val, tick)=>val)
.TakeUntil(maxTime)
.Dump();
}
//LinqPad示例
void Main()
{
var interval=可观测的时间间隔(TimeSpan.From毫秒(250));
var maxTime=可观测计时器(时间跨度从秒(10))开始);
IEnumerable lazySource=可枚举的范围(0100);
lazySource.ToObservable()
.Zip(间隔,(val,tick)=>val)
.TakeUntil(最大时间)
.Dump();
}
*也就是说,其他开发人员易于维护和理解乔恩和往常一样,一针见血;您还可以使用Observable.Create创建自定义流。此外,如果超时窗口已超过,且管理流上没有信号,则超时会抛出。@JerKimball:Ah,但如果原始流仍在生成,则不会抛出(并停止流)?在这种情况下,这将是不好的…因为答案可能是正确的-我突然意识到,在我的具体情况下,最好使用“拉”而不是“推”,因为从处理管道中不断拉假设比推然后订阅感觉更自然。但是你的回答确实帮助我理解了我真正想做的事情!是的,只要触发器流上的事件在指定的时间内出现,错误条件就不会被触发。看起来不错,尽管总是为Observable.Timer指定一个显式的调度程序,我会内联'Timer'变量。Jon和往常一样,是现场的;您还可以使用Observable.Create创建自定义流。此外,如果超时窗口已超过,且管理流上没有信号,则超时会抛出。@JerKimball:Ah,但如果原始流仍在生成,则不会抛出(并停止流)?在这种情况下,这将是不好的…因为答案可能是正确的-我突然意识到,在我的具体情况下,最好使用“拉”而不是“推”,因为从处理管道中不断拉假设比推然后订阅感觉更自然。但是你的回答确实帮助我理解了我真正想做的事情!是的,只要触发器流上的事件在指定的时间内出现,就不会触发错误条件。看起来不错,不过始终为Observable.Timer指定一个显式调度程序,我会内联'Timer'变量。