public void DisposeFromCallback() { for (int i = 0; i < 100; i++) { AutoResetEvent timerDone = new AutoResetEvent(false); VersionedTimer <int> timer = null; bool failed = false; VersionedTimerCallback <int> callback = (int state, long version) => { try { timer.Dispose(); timerDone.Set(); } catch { failed = true; throw; } }; timer = new VersionedTimer <int>(123, callback); timer.Change(10, Timeout.Infinite, 1); Assert.IsTrue(timerDone.WaitOne(5 * 1000), "Timer did not fire"); Assert.IsFalse(failed, "Timer crashed during callback."); } }
public void VerifyDisposalNotify_Pending() { for (int i = 0; i < 100; i++) { VersionedTimer <int> timer; using (var disposeNotify = new AutoResetEvent(false)) using (var callbackCanContinue = new AutoResetEvent(false)) using (var callbackStarted = new AutoResetEvent(false)) { VersionedTimerCallback <int> callback = (int state, long version) => { callbackStarted.Set(); callbackCanContinue.WaitOne(10 * 1000); }; timer = new VersionedTimer <int>(123, callback); timer.Change(10, Timeout.Infinite, 0); Assert.IsTrue(callbackStarted.WaitOne(5 * 1000), "Timer did not fire."); timer.Dispose(disposeNotify); callbackCanContinue.Set(); Assert.IsTrue(disposeNotify.WaitOne(5 * 1000), "Timer disposal notification did not fire."); } } }
public void DisposeDuringCallbackFromUser() { for (int i = 0; i < 100; i++) { VersionedTimer <int> timer; using (var callbackCanContinue = new AutoResetEvent(false)) using (var callbackStarted = new AutoResetEvent(false)) { VersionedTimerCallback <int> callback = (int state, long version) => { callbackStarted.Set(); callbackCanContinue.WaitOne(10 * 1000); }; timer = new VersionedTimer <int>(0, callback); timer.Change(10, Timeout.Infinite, 1); Assert.IsTrue(callbackStarted.WaitOne(5 * 1000), "Timer never fired."); timer.Dispose(); callbackCanContinue.Set(); } } }
/// <summary> /// Initializes a new instance of the VersionedTimer class. /// </summary> /// <param name="state">A value to be provided to the callback method.</param> /// <param name="callback">A method to invoke when the timer elapses.</param> public VersionedTimer(T state, VersionedTimerCallback <T> callback) { if (callback == null) { throw new ArgumentNullException(nameof(callback), "Must provide a callback method."); } if (ExecutionContext.IsFlowSuppressed() == false) { this.userExecContext = ExecutionContext.Capture(); } this.state = state; this.callback = callback; }