public virtual bool DoTimedWait(IQueuedSync sync, TimeSpan duration)
{
lock (this)
{
if (sync.Recheck(this) || !_waiting)
{
return true;
}
if (duration.Ticks <= 0)
{
_waiting = false;
return false;
}
var deadline = DateTime.UtcNow.Add(duration);
try
{
for (;;)
{
Monitor.Wait(this, duration);
if (!_waiting) // definitely signalled
return true;
duration = deadline.Subtract(DateTime.UtcNow);
if (duration.Ticks <= 0) // time out
{
_waiting = false;
return false;
}
}
}
catch (ThreadInterruptedException ex)
{
if (_waiting) // no notification
{
_waiting = false; // invalidate for the signaller
throw ex.PreserveStackTrace();
}
// thread was interrupted after it was notified
Thread.CurrentThread.Interrupt();
return true;
}
}
}