public bool Enqueue(T value, TimeSpan timeout) { _monitor.Lock(); try { if (_receiveRequests.Count > 0) { var receiver = _receiveRequests.First !; _receiveRequests.RemoveFirst(); receiver.Value.Element = value; receiver.Value.IsDone = true; receiver.Value.Condition.Signal(); return(true); } if (timeout == TimeSpan.Zero) { return(false); } var node = _sendRequests.AddLast(new SendRequest(_monitor.NewCondition(), value)); var deadline = Deadline.FromTimeout(timeout); while (true) { TimeSpan remaining = deadline.Remaining(); try { node.Value.Condition.Await(remaining); } catch (ThreadInterruptedException) { if (node.Value.IsDone) { Thread.CurrentThread.Interrupt(); return(true); } _sendRequests.Remove(node); throw; } if (node.Value.IsDone) { return(true); } remaining = deadline.Remaining(); if (remaining <= TimeSpan.Zero) { _sendRequests.Remove(node); return(false); } } } finally { _monitor.Unlock(); } }
public void Await(TimeSpan timeout) { Monitor.Enter(_conditionMonitor); _parentLock.Unlock(); try { Monitor.Wait(_conditionMonitor, timeout); } finally { Monitor.Exit(_conditionMonitor); _parentLock.LockNonInterruptibly(out var wasInterrupted); if (wasInterrupted) { throw new ThreadInterruptedException(); } } }