I am receiving messages from MSMQ. An event is fired when a message is received, in some situations a delay be required before the event is fired. At the moment I have a Task.Delay
to wait for the specified time before firing the event. I am wondering if anyone has a better solution or can see any problems in my current solution:
private List<Task> _delayTasks = new List<Task>();
private void PeekComplete(object sender, msmq.PeekCompletedEventArgs e)
{
//..code to get mesage off the queue...
double delay = _messageTimeOut.TimeOutRequired(messageBody);
if (delay > 0)
{
CreateDelayTask(delay, messageBody);
WaitDelays();
}
else
{
_OnMessageReceived?.Invoke(messageBody);
ProcessingCounter.Decrement();
}
GetNextMessage();
}
private void WaitDelays()
{
while (_delayTasks.Count > 0)
{
int index = -1;
try
{
index = Task.WaitAny(_delayTasks.ToArray());
}
finally
{
if (index > -1)
_delayTasks.RemoveAt(index);
}
}
}
private void CreateDelayTask(double milliSecondsTimeOut, string messageBody)
{
var delay = (int)Math.Ceiling(milliSecondsTimeOut);
var task = Task.Delay(delay).ContinueWith((antecedent) =>
{
try
{
_OnMessageReceived?.Invoke(messageBody);
}
catch (Exception ex)
{
_OnMessageReceivedError?.Invoke(ex, messageBody);
}
finally
{
ProcessingCounter.Decrement();
}
});
_delayTasks.Add(task);
}