Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>This is pretty easy to solve with a timed latch. A latch is synchronization mechanism that is either opened or closed. When open threads are allowed to pass through. When closed threads cannot get through. A timed latch is one that will automatically reopen or reclose after a certain amount of time has elapsed. In this case we want a "normally opened" latch so the behavior is biased towards staying open. That means the latch will reopen automatically after the timeout, but close only if <code>Close</code> is explicitly called. Multiple calls to <code>Close</code> will reset the timer.</p> <pre><code>static NormallyOpenTimedLatch LatchThis = new NormallyOpenTimedLatch(t2); static NormallyOpenTimedLatch LatchThat = new NormallyOpenTimedLatch(t1); static void DoThis() { LatchThis.Wait(); // Wait for it open. DoThisStuff(); LatchThat.Close(); } static void DoThat() { LatchThat.Wait(); // Wait for it open. DoThatStuff(); LatchThis.Close(); } </code></pre> <p>And we can implement our timed latch like the following.</p> <pre><code>public class NormallyOpenTimedLatch { private TimeSpan m_Timeout; private bool m_Open = true; private object m_LockObject = new object(); private DateTime m_TimeOfLastClose = DateTime.MinValue; public NormallyOpenTimedLatch(TimeSpan timeout) { m_Timeout = timeout; } public void Wait() { lock (m_LockObject) { while (!m_Open) { Monitor.Wait(m_LockObject); } } } public void Open() { lock (m_LockObject) { m_Open = true; Monitor.PulseAll(m_LockObject); } } public void Close() { lock (m_LockObject) { m_TimeOfLastClose = DateTime.UtcNow; if (m_Open) { new Timer(OnTimerCallback, null, (long)m_Timeout.TotalMilliseconds, Timeout.Infinite); } m_Open = false; } } private void OnTimerCallback(object state) { lock (m_LockObject) { TimeSpan span = DateTime.UtcNow - m_TimeOfLastClose; if (span &gt; m_Timeout) { Open(); } else { TimeSpan interval = m_Timeout - span; new Timer(OnTimerCallback, null, (long)interval.TotalMilliseconds, Timeout.Infinite); } } } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload