public void Invoke(int notificationId, IInvokable message)
{
// Keep processing order
if (_isKeepingOrder)
{
var expectedNotification = _lastNotificationId + 1;
if (expectedNotification <= 0)
expectedNotification = 1;
if (expectedNotification != notificationId)
{
// keep outOfOrderQueue in order
var fi = _outOfOrderQueue.FindIndex(i => notificationId < i.Item1);
if (fi != -1)
_outOfOrderQueue.Insert(fi, Tuple.Create(notificationId, message));
else
_outOfOrderQueue.Add(Tuple.Create(notificationId, message));
return;
}
_lastNotificationId = expectedNotification;
}
// Process message
InvokeInternal(message);
// Check outOfOrderQueue if we can process further messages in order
if (_isKeepingOrder)
{
while (_outOfOrderQueue.Count > 0)
{
var expectedId = _lastNotificationId + 1;
if (expectedId <= 0)
expectedId = 1;
var item = _outOfOrderQueue[0];
if (expectedId != item.Item1)
break;
_outOfOrderQueue.RemoveAt(0);
_lastNotificationId = expectedId;
InvokeInternal(item.Item2);
}
}
}