代码之家  ›  专栏  ›  技术社区  ›  Martin Moser

带Rx的运行和

  •  3
  • Martin Moser  · 技术社区  · 14 年前

    一定有人已经解决了。 那价值不过是一大笔钱。

    有什么办法吗?

    马丁

    2 回复  |  直到 14 年前
        1
  •  4
  •   Ronald Wildenberg    14 年前

    下面的解决方案包括使用 Observable.Scan . 状态作为具有 int DateTime

    var events = Observable.FromEvent<YourEventArgs>(
        h => SomeEvent += h, h => SomeEvent -= h);
    var runningSums =
        events.Scan(new List<Tuple<int, DateTime>>(),
                    (l, e) =>
                    {
                        var now = DateTime.Now;
                        // Add last event data to list.
                        l.Add(Tuple.Create(e.EventArgs.Money, now));
                        // Return the correct part of the list (everything
                        // from the last ten minutes).
                        return l.Where(t => (now - t.Item2) <
                                       TimeSpan.FromMinutes(10)).ToList();
                     })
              .Select(l => l.Sum(t => t.Item1));
    runningSums.Subscribe(sum => Console.WriteLine(sum));
    

    编辑

    var events = Observable.FromEvent<YourEventArgs>(
        h => SomeEvent += h, h => SomeEvent -= h);
    var runningSums =
        events.Scan(Tuple.Create(new List<Tuple<int, DateTime>>(),
                                 DateTime.Now - TimeSpan.FromMinutes(10)),
                    (l, e) =>
                    {
                        var now = DateTime.Now;
                        l.Item1.Add(Tuple.Create(e.EventArgs.Nr, now));
                        // if (trimming-condition) then trim front of list...
                        return Tuple.Create(l.Item1, now - TimeSpan.FromMinutes(10));
                    })
              .Select(l => l.Item1.Where(t => t.Item2 > l.Item2).Sum(t => t.Item1));
    runningSums.Subscribe(sum => Console.WriteLine(sum));
    
        2
  •  1
  •   pointernil    14 年前

    好吧,看看下面的解决方案。它建立在前面介绍的解决方案的基础上,但是为了效率(和可读性,我认为)而放弃了纯函数样式。它还重用了内置类型 Timestamped 为了追踪时间。。。

    干杯

        public static class RxEntentsions
            {
                class TimeLimitedList<T>
                {
                    public List<Timestamped<T>> Values = new List<Timestamped<T>>();
                    TimeSpan span;
                    public TimeLimitedList(TimeSpan sp) { span = sp; }
                    public void Add(Timestamped<T> v)
                    {
                        Values.Add(v);
                        Values.RemoveAll(a => a.Timestamp < (DateTime.Now - span));
                    }
                }
    
                public static IObservable<List<Timestamped<TSource>>> SlidingWindow<TSource>(this IObservable<Timestamped<TSource>> source, TimeSpan slidingWindow)
                {
                    return source.Scan0(new TimeLimitedList<TSource>(slidingWindow), (acc, v) => { acc.Add(v); return acc; }).Select(a => a.Values);
                }
            }
    
    
        static void Main(string[] args)
        {
            var gen = Observable.Interval(TimeSpan.FromSeconds(0.25d)).Timestamp();
            gen.SlidingWindow(TimeSpan.FromSeconds(1)).Subscribe(slw => {slw.ForEach(e=> Console.WriteLine(e)); Console.WriteLine("--------");});
            Console.ReadLine();
        }