internal override void SystemClockChanged(object sender, SystemClockChangedEventArgs args) { var target = default(WeakReference <LocalScheduler>); foreach (var entries in SystemClock.SystemClockChanged) { if (entries.TryGetTarget(out var local) && local == this) { target = entries; break; } } SystemClock.SystemClockChanged.Remove(target); }
/// <summary> /// Callback invoked when a system clock change is observed in order to adjust and reevaluate /// the internal scheduling queues. /// </summary> /// <param name="args">Currently not used.</param> /// <param name="sender">Currently not used.</param> internal void SystemClockChanged(object sender, SystemClockChangedEventArgs args) { lock (_gate) { lock (s_gate) { // // Best-effort cancellation of short term work. A check for presence in the hash set // is used to notice race conditions between cancellation and the timer firing (also // guarded by the same gate object). See checks in ExecuteNextShortTermWorkItem. // #if !NO_HASHSET foreach (var d in _shortTermWork) #else foreach (var d in _shortTermWork.Keys) #endif { d.Dispose(); } _shortTermWork.Clear(); // // Transition short term work to the long term queue for reevaluation by calling the // EvaluateLongTermQueue method. We don't know which direction the clock was changed // in, so we don't optimize for special cases, but always transition the whole queue. // Notice the short term queue is bounded to SHORTTERM length. // while (_shortTerm.Count > 0) { var next = _shortTerm.Dequeue(); s_longTerm.Enqueue(next); } // // Reevaluate the queue and don't forget to null out the current timer to force the // method to create a new timer for the new first long term item. // s_nextLongTermWorkItem = null; EvaluateLongTermQueue(null); } } }