async void OnElapsed(object context) { if (!this.stopGuard.TryLock()) { return; } try { await Elapsed.InvokeAsync(this, new TimerElapsedEventArgs(context, CancellationToken.None)); } finally { Interlocked.Increment(ref this.elapsed); this.stopGuard.Release(); // Try to change one-shot state to 3 (stopping by inside) only if it is 1 (one-shot not fired). If the // current value is 1 that mean this method have responsibility to clean up resources. if (Interlocked.CompareExchange(ref this.oneShotState, 3, 1) == 1) { Stop(); } } }