简体   繁体   中英

C# Rx Observable collapse individual events to batches

I have an IObservable that is streaming individual events and I want to batch these up into another IObservable that streams batches of events. I had a stab at writing it like this;

class MyEvent
{
    public string Description {get; set;}
}

class EventsBatch
{
    public MyEvent[] Batch {get; set;}
}

IObservable<EventsBatch> ConvertToBatches(IObservable<MyEvent> observable, int batchSize)
{
    var eventsAccumulator = new List<MyEvent>();
    var subject = new ReplaySubject<EventsBatch>();
    var completionSource = new TaskCompletionSource<object>();

    var subscription = observable.Subscribe(events =>
        {
            eventsAccumulator.Add(events);
            if (eventsAccumulator.Count == batchSize)
            {
                subject.OnNext(new EventsBatch { Batch = eventsAccumulator.ToArray() });
                eventsAccumulator.Clear();
            }
        },
        ex => completionSource.TrySetException(ex),
        () =>
        {
            subject.OnNext(new EventsBatch { Batch = eventsAccumulator.ToArray() });
            subject.OnCompleted();
            completionSource.TrySetResult(null);
        });

    completionSource.Task.Wait();
    subscription.Dispose();
    subject.OnCompleted();
    return subject;
}

This blocks until the entire stream is complete before streaming the resulting batches, which is going to have terrible performance in the best case and never return in the case of an indefinite stream.

What is the correct way to do this?

I think I may have figured it out;

IObservable<EventsBatch> convertToBatches(IObservable<MyEvent> observable, int batchSize)
{
    return observable.Buffer(batchSize).Select(e => new EventsBatch{ Batch = e.ToArray() });
}

Please suggest better solution if possible

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM