internal void AddPendingEvent(PendingEvent ev) { if (IsShuttingDown) // don't care about adding anything if we're shutting down { return; } lock (_lockHeap) { _eventHeap.Push(ev); } }
// returns the index of the added item int Add(PendingEvent ev) { // check if we need to resize if (_events.Length == Count) { var bigger = new PendingEvent[_events.Length * 2]; Array.Copy(_events, bigger, Count); _events = bigger; } _events[Count] = ev; return(Count++); // postfix is intentional }
public void Push(PendingEvent ev) { if (ev == null) { throw new ArgumentNullException(nameof(ev)); } var ei = Add(ev); while (ei > 0) { var pi = ParentIndex(ei); if (ev.IsEarlierThan(_events[pi])) { Swap(ei, pi); ei = pi; } else { break; } } }
internal bool IsEarlierThan(PendingEvent ev) { return ScheduledTime < ev.ScheduledTime; }
// returns the index of the added item private int Add(PendingEvent ev) { // check if we need to resize if (_events.Length == Count) { var bigger = new PendingEvent[_events.Length * 2]; Array.Copy(_events, bigger, Count); _events = bigger; } _events[Count] = ev; return Count++; // postfix is intentional }
public void Push(PendingEvent ev) { if (ev == null) throw new ArgumentNullException(nameof(ev)); var ei = Add(ev); while (ei > 0) { var pi = ParentIndex(ei); if (ev.IsEarlierThan(_events[pi])) { Swap(ei, pi); ei = pi; } else { break; } } }
internal async Task RunPendingEvent(PendingEvent ev) { var eventTime = ev.ScheduledTime; var execLockTaken = false; try { lock (_scheduleLock) { if (ev.RunId != _runId) return; // take execution lock execLockTaken = Interlocked.CompareExchange(ref _execLocked, 1, 0) == 0; if (execLockTaken) PrevEvent = eventTime; // set this here while we're still in the schedule lock } if (execLockTaken) { try { if (Callback != null) Callback(this, eventTime); else await AsyncCallback(this, eventTime).ConfigureAwait(false); } catch (Exception ex) { RaiseException(ex); } } } finally { if (execLockTaken) _execLocked = 0; // release exec lock } // figure out the next time to run the schedule lock (_scheduleLock) { if (ev.RunId != _runId) return; try { var next = Schedule.Next(); if (next <= eventTime) next = Schedule.Next(eventTime); NextEvent = next; QueueNextEvent(); } catch (Exception ex) { _runId++; IsScheduleRunning = false; RaiseException(new ScheduleCrashException("Schtick Schedule has been terminated because the next valid time could not be found.", this, ex)); } } }
internal void AddPendingEvent(PendingEvent ev) { if (IsShuttingDown) // don't care about adding anything if we're shutting down return; lock (_lockHeap) { _eventHeap.Push(ev); } }
internal async Task RunPendingEvent(PendingEvent ev) { var eventTime = ev.ScheduledTime; var execLockTaken = false; try { lock (_scheduleLock) { if (ev.RunId != _runId) { return; } // take execution lock execLockTaken = Interlocked.CompareExchange(ref _execLocked, 1, 0) == 0; if (execLockTaken) { PrevEvent = eventTime; // set this here while we're still in the schedule lock } } if (execLockTaken) { try { if (Callback != null) { Callback(this, eventTime); } else { await AsyncCallback(this, eventTime).ConfigureAwait(false); } } catch (Exception ex) { RaiseException(ex); } } } finally { if (execLockTaken) { _execLocked = 0; // release exec lock } } // figure out the next time to run the schedule lock (_scheduleLock) { if (ev.RunId != _runId) { return; } try { var next = Schedule.Next(); if (next <= eventTime) { next = Schedule.Next(eventTime); } NextEvent = next; QueueNextEvent(); } catch (Exception ex) { _runId++; IsScheduleRunning = false; RaiseException(new ScheduleCrashException("Schtick Schedule has been terminated because the next valid time could not be found.", this, ex)); } } }
internal bool IsEarlierThan(PendingEvent ev) { return(ScheduledTime < ev.ScheduledTime); }