Observable from list of timetamps

旧时模样 提交于 2019-12-19 09:46:40

问题


If I have a list of objects that contains a timestamp - how can I make an observable that fire events at the relative time between the timestamps?

Eg. if I have three objects with timestamps 2014-01-01 10:30, 2014-01-01 10:45 and 2014-01-01 11:30, I want the first event to fire right away, then the next 15 minutes later, and the last one 45 minutes after that.

How can I speed up the process, so that 1 minute equals 1 second? So the first event would fire right away as before, but the next would come 15 seconds later instead of 15 minutes and so on.


回答1:


Lots of ways to do this I'm sure, but here's a quick sample using Observable.Generate to schedule events at a particular time. It uses a list of events - but given it works with an iterator, you can easily adapt it to use another source:

void Main()
{
    var now = DateTime.Now;

    var events = new List<Tuple<DateTime, string>> {
        Tuple.Create(now.AddSeconds(5), "A"),
        Tuple.Create(now.AddSeconds(10), "B"),
        Tuple.Create(now.AddSeconds(15), "C")
    };

    var eventSource = Observable.Generate(
        (IEnumerator<Tuple<DateTime,string>>)events.GetEnumerator(),
        s => s.MoveNext(),
        s => s,
        s => s.Current.Item2, // the data
        s => s.Current.Item1); // the timing

    eventSource.Subscribe(Console.WriteLine);                       
}

This writes out "A", "B" and "C" and 5, 10 and 15 seconds after start-up.

To speed up time, you can put some logic around how the scheduled time is interpreted. Another way it to use the HistoricalScheduler. See this answer for some insight on that.




回答2:


Easiest way is to merge an enumerable of observables like so

IEnumerable<Tuple<DateTimeOffset,string>> timeStamps = ...;
IObservable<Tuple<DateTimeOffset,string>> eventStamps = timeStamps
    .Select(s => Observable.Timer(s.Item1).Select(e=>s))
    .Merge();

As per James World's answer, to speed or slow time, you can add the historical scheduler as a second argument to Timer. (Give him the points for that bit. I didn't know about that before I read his answer )

Observable.Timer(s.Item1, historicalScheduler)

If you are wondering why DateTimeOffset rather than DateTime look at DateTime vs DateTimeOffset

The nice thing is that the code above works if timeStamps is either IEnumerable or IObservable. There is an overload of merge that works for either.



来源:https://stackoverflow.com/questions/22255205/observable-from-list-of-timetamps

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!