Imagine we consume a web socket with really high fast finance data. In peak times the web socket method is called hundreds to thousands times per second.
We have a condition in our web socket method which goes from time to time to true. And in this case another method should be called. But only once. Due to the execution speed of the method it is really hard to prevent double execution. The code looks like this:
private readonly ConcurrentDictionary<string, bool> _inExecution = new ConcurrentDictionary<string, bool>();
private void SubscribeToSocket()
{
_socket.Connect();
var subscription = SocketSubscriptions.CreateSubsription(data =>
{
Task.Run(async () =>
{
// read data
if (condition)
{
// call method only once
await Execute(key);
condition = false;
}
}
}
}
private async Task Execute(string key)
{
// Even with this statement the code calls are too fast and sometimes gets executed twice
if (!_inExecution[key])
{
_inExecution[key] = true;
// do something..
}
}
I already tried to prevent a double execution with a random wait before the Execute() method. Like this:
if (condition)
{
var rnd = new Random();
await Task.Delay(rnd.Next(15, 115));
// call method only once
await Execute(key);
condition = false;
}
But even this got executed twice in some special cases. Is there a better way to prevent that?