void CloseAndFlush() { lock (_stateLock) { if (_unloading) { return; } _unloading = true; } #if NO_TIMER _timer.Dispose(); #else var wh = new ManualResetEvent(false); if (_timer.Dispose(wh)) { wh.WaitOne(); } #endif OnTick(); }
public void WhenOverlapsShouldProcessOneAtTime_OnTick() { var userHandlerOverlapped = false; PortableTimer timer = null; timer = new PortableTimer( async _ => { if (Monitor.TryEnter(timer)) { try { // ReSharper disable once PossibleNullReferenceException timer.Start(TimeSpan.Zero); Thread.Sleep(20); } finally { Monitor.Exit(timer); } } else { userHandlerOverlapped = true; } }); timer.Start(TimeSpan.FromMilliseconds(1)); Thread.Sleep(50); timer.Dispose(); Assert.False(userHandlerOverlapped); }
public void WhenDisposedWillThrow_OnStart() { var wasCalled = false; var timer = new PortableTimer(async delegate { wasCalled = true; }); timer.Start(TimeSpan.FromMilliseconds(100)); timer.Dispose(); Assert.False(wasCalled); Assert.Throws <ObjectDisposedException>(() => timer.Start(TimeSpan.Zero)); }
public void CanBeDisposedFromMultipleThreads() { PortableTimer timer = null; timer = new PortableTimer(async _ => timer.Start(TimeSpan.FromMilliseconds(1))); timer.Start(TimeSpan.Zero); Thread.Sleep(50); Parallel.For(0, Environment.ProcessorCount * 2, _ => timer.Dispose()); }
public void CanBeDisposedFromMultipleThreads() { PortableTimer timer = null; // ReSharper disable once PossibleNullReferenceException timer = new PortableTimer(async _ => timer.Start(TimeSpan.FromMilliseconds(1))); timer.Start(TimeSpan.Zero); Thread.Sleep(50); Parallel.For(0, Environment.ProcessorCount * 2, _ => timer.Dispose()); }
public void TimerShouldThrowExceptionOnStartWhenDisposed() { var wasCalled = false; var timer = new PortableTimer(async() => { wasCalled = true; }); timer.Start(TimeSpan.FromMilliseconds(100)); timer.Dispose(); wasCalled.ShouldBeFalse(); Should.Throw <ObjectDisposedException>(() => timer.Start(TimeSpan.Zero)).ObjectName .ShouldBe(nameof(PortableTimer)); }
private void CloseAndFlush() { lock (stateLock) { if (unloading) { return; } unloading = true; } timer.Dispose(); OnTick().GetAwaiter().GetResult(); }
void CloseAndFlush() { lock (_stateLock) { if (!_started || _unloading) { return; } _unloading = true; } _timer.Dispose(); OnTick(); }
private void CloseAndFlush() { lock (_stateLock) { if (!_started || _unloading) { return; } _unloading = true; } _timer.Dispose(); // This is the place where SynchronizationContext.Current is unknown and can be != null // so we prevent possible deadlocks here for sync-over-async downstream implementations ResetSyncContextAndWait(OnTick); }