Search code examples
c#.netlinqtimerbuffering

C# .NET - Buffer messages w/Timer


I need to implement a message buffering system that is also timed based.

What I need to do is store instances of my class and then send them forward either when I reach 100 instances or when 1 minute has passed.

Basically:

List<Message> messages;

public void GotNewMessage(Message msg)
{
    messages.add(msg);

    if (messages.count() == 100 || timer.elapsed(1 minute))
    {
        SendMessages(messages);
        messages.clear()
    }
}

I just can't seem to figure out how to implement this without an excessive use of locks which will slow down the process considerably. Does anyone know of a good way to implement such a system? Thanks in advance.


Solution

  • There is a fantastic library for these kind of requirements (combine time with sequences), it is Reactive Extensions. See https://github.com/Reactive-Extensions/Rx.NET

    You could then write something like

    void Main()
    {
        messages
            .Buffer(TimeSpan.FromMinutes(1), 100) // Buffer until 100 items or 1 minute has elapsed, whatever comes first.
            .Subscribe(msgs => SendMessages(msgs));     
    }
    
    Subject<Message> messages = new Subject<Message>();
    
    public void GotNewMessage(Message msg)
    {
        messages.OnNext(msg);
    }
    

    Note: this is not production ready but it shows the basic of how to do it. Depending on where you het the messages from there are better ways to create an Observable to subscribe to.

    More references:

    If your message are received using an event you can link the event to a RX stream, see https://msdn.microsoft.com/en-us/library/hh242978(v=vs.103).aspx and https://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.fromeventpattern(v=vs.103).aspx