public void AnonymousDisposable() { var controller = new Mock <IEventController>(); var disposable = new AnonymousDisposable(() => controller.Object.RaiseEvent("Disposed")); disposable.Dispose(); disposable.Dispose(); disposable.Dispose(); controller.Verify(c => c.RaiseEvent("Disposed"), Times.Once); }
public void WhenDisposedTwice_ThenInvokesActionOnce() { var called = 0; using (var disposable = new AnonymousDisposable(() => called++)) { disposable.Dispose(); disposable.Dispose(); } Assert.Equal(1, called); }
public void when_Dispose_is_called_Action_is_called() { var actionWasCalled = false; var anonymousDisposable = new AnonymousDisposable(() => actionWasCalled = true); Assert.That(actionWasCalled, Is.False); anonymousDisposable.Dispose(); Assert.That(actionWasCalled, Is.True); }
/// <summary>Schedules the given action to run asynchronously on the queue after dueTime.</summary> /// <remarks>The function is not guaranteed to run at dueTime as the queue may be busy, it will run when next able.</remarks> /// <param name="dueTime">Delay before running the action</param> /// <param name="action">The function to run</param> /// <returns>A disposable token which you can use to cancel the async action if it has not run yet. /// It is always safe to dispose this token, even if the async action has already run</returns> public virtual IDisposable DispatchAfter(TimeSpan dueTime, Action action) { IDisposable cancel = null; IDisposable timer = null; lock (m_schedulerLock) { if (m_isDisposed) throw new ObjectDisposedException("SerialQueue", "Cannot call DispatchAfter on a disposed queue"); timer = m_threadPool.Schedule(dueTime, () => { lock(m_schedulerLock) { m_timers.Remove(timer); if (cancel == null || m_isDisposed) // we've been canceled OR the queue has been disposed return; // we must call DispatchAsync while still holding m_schedulerLock to prevent a window where we get disposed at this point cancel = DispatchAsync(action); } }); m_timers.Add(timer); } cancel = new AnonymousDisposable(() => { lock (m_schedulerLock) m_timers.Remove(timer); timer.Dispose(); }); return new AnonymousDisposable(() => { lock (m_schedulerLock) { if (cancel != null) { cancel.Dispose(); // this will either cancel the timer or cancel the DispatchAsync depending on which stage it's in cancel = null; } } }); }
public void TearDown() { cleanup.Dispose(); }