条件延迟

时间:2016-12-03 12:32:07

标签: .net system.reactive reactivex

有一个代码:

someObservable.Select(x => getY(x));    
Y getY(X x)
{
  if (x.Value == X.ABC)
    return new Y(1);
  else
    return new Y(2);
}

在某些情况下,我需要在一段时间后仔细检查x.Value。 最简单和最糟糕的解决方案是使用Thread.Sleep:

Y getY(X x)
{
  if (x.Value == X.ABC)
    return new Y(1);
  else
  if (x.SomethingElse == true)
  {
     Thread.Sleep(timeout);
     if (x.Value == X.ABC)
       return new Y(1);
     else
       return new Y(2);
  }
}

这里的代码是什么? 我需要按照收到的方式订购活动。 这意味着如果我有延迟并且我得到一个新值,它必须等待处理。

1 个答案:

答案 0 :(得分:0)

如果这是一般性问题,我建议您实现自定义运算符。 延迟方法具有过载,其接受另一个可观察的控制延迟定时。在该示例中,偶数数字会立即推送,而奇数数字会被延迟;

Observable.Interval(TimeSpan.FromSeconds(1))
          .Delay(i => (i % 2 == 0) ? Observable.Return(0L) : Observable.Timer(TimeSpan.FromSeconds(0.9)))
          .Subscribe(Console.WriteLine);

编辑: 这是一个更简单的,保持延迟的命令运算符:

  static IObservable<T> DelayOrdered<T>(this IObservable<T> observable, Func<T, TimeSpan> delaySelector, IScheduler scheduler = default(IScheduler))
        {
            scheduler = scheduler ?? DefaultScheduler.Instance;
            return Observable.Create<T>(observer =>
            {
                var now = scheduler.Now;

                return observable
                       .Subscribe(value =>
                {
                    now = now.Add(delaySelector(value));
                    scheduler.Schedule(now, () => observer.OnNext(value));
                });
            });
        }

用法:

  Observable.Interval(TimeSpan.FromSeconds(0.2))
                      .DelayOrdered(i => (i % 2 == 0) ? TimeSpan.Zero : TimeSpan.FromSeconds(1))
                      .Subscribe(Console.WriteLine);

订单将被保留,因为绝对预定时间只会增加。