Exemple #1
0
        private void ThreadPoolCallback(object state)
        {
            DueTimer due = (DueTimer)state;

            due.Run();
        }
Exemple #2
0
        private void PrimeTimerCallback(object ignored)
        {
            DueTimer?firstElapsed = null;

            lock (this)
            {
                TimeSpan currentTime   = this.timeBase.Elapsed;
                TimeSpan lowestDueTime = TimeSpan.MaxValue;

                this.nextPrimeTime = TimeSpan.MaxValue;

                // Game plan:
                // 1) Scan the list for timers that are expired.
                // 2) The first timer that's expired, we'll save and execute on this thread. Saves
                //    threading overhead since it's a very common case.
                // 3) We need to scan over the list to find out what the next prime timeout should be.
                // 4) Any timer we invoke, we need to read its version UNDER THIS LOCK and save it off.
                // 5) Don't execute any timer callbacks under this lock.
                // 6) If we need to fire more than one timer, we'll queue them to the threadpool.
                // 7) If a timer elapsed and is not periodic, then delete it from the queue.

                for (int i = 0; i < this.timerList.Count; /* conditional increment */)
                {
                    bool delete = false;
                    var  timer  = this.timerList[i];

                    // Find out if this timer has elapsed.
                    if (timer.NextTimeout <= currentTime)
                    {
                        // Fire the timer
                        if (firstElapsed == null)
                        {
                            firstElapsed = new DueTimer(timer);
                        }
                        else
                        {
                            EnqueueTimerCallback(new DueTimer(timer));
                        }

                        // Reset or delete the timer.
                        if (timer.Period == Timeout.InfiniteTimeSpan)
                        {
                            delete            = true;
                            timer.NextTimeout = Timeout.InfiniteTimeSpan;
                        }
                        else
                        {
                            timer.NextTimeout += timer.Period;
                        }
                    }

                    // Track the next timestamp for the prime timer.
                    if (timer.NextTimeout < lowestDueTime)
                    {
                        lowestDueTime = timer.NextTimeout;
                    }

                    // List-meta: We're either going to delete the item we're on (thus advancing the
                    // for loop), or we're going to leave the current item and simply go to the next index.
                    if (delete)
                    {
                        this.timerList.RemoveAt(i);
                    }
                    else
                    {
                        i++;
                    }
                }

                if (lowestDueTime != TimeSpan.MaxValue)
                {
                    EnsurePrimerTimerDueBy(lowestDueTime);
                }
            }

            // Fire off the first elapsed timer, if one exists, but make sure to do so outside the lock.
            if (firstElapsed != null)
            {
                firstElapsed.Value.Run();
            }
        }
Exemple #3
0
 private void EnqueueTimerCallback(DueTimer due)
 {
     ThreadPool.QueueUserWorkItem(ThreadPoolCallback, due);
 }