17 using System.Threading;
19 using System.Collections.Generic;
31 private readonly Thread _pulseThread;
32 private readonly Queue<DateTime> _work;
33 private readonly ManualResetEvent _event;
34 private readonly CancellationTokenSource _tokenSource;
47 _tokenSource =
new CancellationTokenSource();
48 _event =
new ManualResetEvent(
false);
49 _work =
new Queue<DateTime>();
50 _pulseThread =
new Thread(() =>
52 while (!_tokenSource.Token.IsCancellationRequested)
54 DateTime nextUtcScheduledEvent;
57 _work.TryDequeue(out nextUtcScheduledEvent);
60 if (nextUtcScheduledEvent ==
default)
62 _event.WaitOne(_tokenSource.Token);
64 if (_tokenSource.Token.IsCancellationRequested)
72 var diff = nextUtcScheduledEvent - timeProvider.
GetUtcNow();
73 while (diff.Ticks > 0)
75 _tokenSource.Token.WaitHandle.WaitOne(diff);
77 diff = nextUtcScheduledEvent - timeProvider.GetUtcNow();
79 if (_tokenSource.Token.IsCancellationRequested)
85 NewEvent?.Invoke(
this, EventArgs.Empty);
87 }) { IsBackground =
true, Name =
"RealTimeScheduleEventService" };
102 _work.Enqueue(utcNow + dueTime);
112 _pulseThread.StopSafely(TimeSpan.FromSeconds(1), _tokenSource);
113 _tokenSource.DisposeSafely();
114 _event.DisposeSafely();