Creating Multiple Timers with Reactive Extensions

后端 未结 3 1430
庸人自扰
庸人自扰 2021-01-16 14:06

I\'ve got a very simple class that I am using to poll a directory for new files. It\'s got the location, a time to start monitoring that location, and an interval (in hours

3条回答
  •  囚心锁ツ
    2021-01-16 14:27

    This is the clearest method I can think of:

    foreach (var thing in things)
    {
        Scheduler.ThreadPool.Schedule(
            thing.StartTime,
            () => {
                    DoWork(thing.Uri); 
                    Observable.Interval(TimeSpan.FromHours(thing.Interval))
                              .Subscribe(_ => DoWork(thing.Uri)));
                  }
    }
    

    The following one is more functional:

    things.ToObservable()
        .SelectMany(t => Observable.Timer(t.StartTime).Select(_ => t))
        .SelectMany(t => Observable.Return(t).Concat(
            Observable.Interval(TimeSpan.FromHours(t.Interval)).Select(_ => t)))
        .Subscribe(t => DoWork(t.Uri));
    

    The First SelectMany creates a stream of things at their scheduled times. The second SelectMany takes this stream and creates a new one that repeats every interval. This needs to be joined to the Observable.Return which produces a value immediately as Observable.Interval's first value is delayed.

    *Note, the first solution requires c#5 or else this will bite you.

提交回复
热议问题