0

I have a high rate of events that can occur for a specific entity and i need to transfer them over a network. The problem is that those event can generate high level of traffic and calculation and that is not desired.

So my question would be what would be the best way to delay the execution of calculation function for a specific amount of time. In my case events doesn't have any actual data that i need to buffer or occurrence order so basically it would be just to start a timer once event occurs and fire it with entity parameter once delay expires.

I could build my own implementation with a timer but it seem that there are already ones that should support it e.g reactive extensions ?

In any case if somebody can point me out to an existing implementation or framework would be greatly appreciated.

Edit

Ok, i have looked at RX observable pattern and it looks like it can do the job. I can see a simple implementation that i could use e.g

 IDisposable handlers;
        Subject<int> subject = new Subject<int>();
        handlers = subject.AsObservable().Sample(TimeSpan.FromSeconds(10))
            .Subscribe(sample =>
        {
            Trace.WriteLine(sample);
        });

Now whenever i want to process event i would call

subject.OnNext(someValue);

The sample should delay the calls to subscribers. Can somebody comment if i am correct with this usage?

NullReference
  • 862
  • 1
  • 11
  • 27
  • There are far too many options available. – B.K. Aug 13 '16 at 09:44
  • some references would be nice. – NullReference Aug 13 '16 at 11:19
  • Sure, the best one I can offer is Concurrency in C# Cookbook. Stephen offers several methods of throttling in various approaches, such as Rx, Dataflow, etc. However, I'm providing it as a courtesy -- you should not expect anyone to provide you with external resource references, as such questions on StackOverflow are considered to be off-topic. – B.K. Aug 13 '16 at 19:17

2 Answers2

0

Here is an example to what you can do:

public class ExpiryDictionarty
{
    Timer timer; //will hanlde the expiry
    ConcurrentDictionary<string, string> state; //will be used to save the last event

    public ExpiryDictionarty(int milisec)
    {
        state = new ConcurrentDictionary<string, string>();
        timer = new Timer(milisec);
        timer.Elapsed += new ElapsedEventHandler(Elapsed_Event);
        timer.Start();
    }

    private void Elapsed_Event(object sender, ElapsedEventArgs e)
    {
        foreach (var key in state.Keys)
        {
            //fire the calculation for each event in the dictionary
        }
        state.Clear();
    }

    public void Add(string key, string value)
    {
        state.AddOrUpdate(key, value);
    }
}

you can create a collection that will save all the events that you receive, once the time ticks you can fire all the events in the collection, because we are using a dictionary we can save only the last event so we don't have to save all the events you get.

Shlomi Haver
  • 954
  • 9
  • 14
0

I suggest you look into Proxy design pattern. Your clients will know only about a proxy and trigger events on the Proxy object. Your Proxy object will contain the logic that determines when to send actual request over the wire. This logic may depend on your requirements. From what I understood, having a boolean switch isEventRaised and checking it within a configurable interval may suffice your requirements (you will reset the flag to false at the end of this interval).

Also, you may check Throttling implementations first and try to figure out whether they will suite your requirements. For example, here is a StackOverflow question about different Throttling methods, which references among others a Token bucket algorithm.

Community
  • 1
  • 1
oldbam
  • 2,397
  • 1
  • 16
  • 24