Tengo una colección de artículos de la siguiente clase:

public class Event
{
    public DateTimeOffset Timestamp;
    public object Data;
}

Quiero crear IObservable<Event> donde cada elemento se publique en el momento de Timestamp en el futuro. ¿Es esto posible con Observable.Delay o tengo que escribir mi propia implementación de IObservable<T>?

Mencionaré que esta estructura es algo así como un archivo de registro. Puede haber decenas de miles de Event elementos, pero solo se publicarán 1-2 por segundo.

2
ghord 18 feb. 2018 a las 18:35

2 respuestas

La mejor respuesta

Si bien mi primera respuesta funciona según lo previsto, el rendimiento de la creación de la secuencia observable no es ideal con cientos de miles de eventos: usted paga un costo de inicialización sustancial (orden de 10 segundos en mi máquina).

Para mejorar el rendimiento, aprovechándome de la naturaleza ya ordenada de mis datos, implementé IEnumerable<Event> personalizado que recorre eventos, cede y duerme entre ellos. Con este IEnumerable uno puede llamar fácilmente a ToObservable<T> y funciona según lo previsto:

IObservable<Event> CreateSimulation(IEnumerable<Event> events)
{
     IEnumerable<Event> simulation()
     {
         foreach(var ev in events)
         {
             var now = DateTime.UtcNow;

             if(ev.Timestamp > now)
             {
                 Thread.Sleep(ev.Timestamp - now);
             }

             yield return ev;          
        }
    }

    return simulation().ToObservable();
}
1
ghord 23 feb. 2018 a las 09:46

Resulta que es muy simple de hacer con la sobrecarga de Observable.Delay que toma un tiempo variable:

//given IEnumerable<Event> events:
var observable = events.ToObservable().Delay(ev => Observable.Timer(ev.Timestamp));
5
ghord 18 feb. 2018 a las 16:06