private void NotificationTimer(ref Int64 interval, ref Int64 ignoreDurationThreshold, ref Boolean hasToStopTimer) { if (interval < 0L) { throw new ArgumentException(@"The ""interval"" cannot be negative.", nameof(interval)); } else if (ignoreDurationThreshold < 0L) { throw new ArgumentException(@"The ""ignoreDurationThreshold"" cannot be negative.", nameof(ignoreDurationThreshold)); } else { var count = 0L; var nextNotification = 0L; var microStopwatch = MicroStopwatch.StartNewMicro(); while (!hasToStopTimer) { var callbackDuration = microStopwatch.ElapsedMicroseconds - nextNotification; var intervalCurrent = Interlocked.Read(ref interval); var ignoreDurationThresholdCurrent = Interlocked.Read(ref ignoreDurationThreshold); nextNotification += intervalCurrent; if (count != Int64.MaxValue) { count++; } else { count = 0L; } var elapsedMicroseconds = 0L; while (((elapsedMicroseconds = microStopwatch.ElapsedMicroseconds) < nextNotification) && !hasToStopTimer) { Thread.SpinWait(10); } var delay = elapsedMicroseconds - nextNotification; if (delay >= ignoreDurationThresholdCurrent) { continue; } else { if (delay < 0L) { delay = 0L; } var e = new MicroTimerElapsedEventArgs(count, elapsedMicroseconds, delay, callbackDuration); this.OnElapsed(e); } } microStopwatch.Stop(); } }
protected virtual void OnElapsed(MicroTimerElapsedEventArgs e) { this.Elapsed?.Invoke(this, e); }