0

什么是正确的 Rx 扩展方法(在 .NET 中)以持续生成事件 N 秒?

通过“继续生成事件 N 秒”,我的意思是它将继续在循环中生成事件,从 DateTime.Now 到 DateTime.Now + TimeSpan.FromSeconds(N)

我正在研究遗传算法,它将产生许多假设并将最成功的假设传播给下一代。需要以某种优雅的方式约束这个家伙。

后来补充:

我实际上已经意识到我需要做拉而不是推,并想出了这样的事情:

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

用法是:

var results = lazySource.SelectMany(item =>
{
    //processing goes here
}).Pull(timeout: TimeSpan.FromSeconds(5), times: numberOfIterations);
4

2 回答 2

4

可能有一种更清洁的方法,但您可以使用:

// 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 了,所以如果这不正确,我深表歉意 - 但值得一试......

于 2013-03-28T22:23:47.740 回答
0

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

*IE。其他开发人员易于维护和理解

于 2013-04-02T08:58:12.280 回答