private bool DiscontinuousWait(ManualResetEventSlim currentPhaseEvent, int totalTimeout, CancellationToken token, long observedPhase)
{
int maxWait = 100; // 100 ms
int waitTimeCeiling = 10000; // 10 seconds
while (observedPhase == CurrentPhaseNumber)
{
// the next wait time, the min of the maxWait and the totalTimeout
int waitTime = totalTimeout == Timeout.Infinite ? maxWait : Math.Min(maxWait, totalTimeout);
if (currentPhaseEvent.Wait(waitTime, token))
return true;
//update the total wait time
if (totalTimeout != Timeout.Infinite)
{
totalTimeout -= waitTime;
if (totalTimeout <= 0)
return false;
}
//if the maxwait exceeded 10 seconds then we will stop increasing the maxWait time and keep it 10 seconds, otherwise keep doubling it
maxWait = maxWait >= waitTimeCeiling ? waitTimeCeiling : Math.Min(maxWait << 1, waitTimeCeiling);
}
//if we exited the loop because the observed phase doesn't match the current phase, then we have to spin to mske sure
//the event is set or the next phase is finished
WaitCurrentPhase(currentPhaseEvent, observedPhase);
return true;
}