示例#1
0
            void SchedulerThread()
            {
                Thread.CurrentThread.Name = "Timer-Scheduler";
                var new_time = new List <Timer> (512);

                while (true)
                {
                    int  ms_wait = -1;
                    long ticks   = GetTimeMonotonic();
                    lock (this) {
                        changed.Reset();
                        //PrintList ();
                        int i;
                        int count = list.Count;
                        for (i = 0; i < count; i++)
                        {
                            Timer timer = (Timer)list.GetByIndex(i);
                            if (timer.next_run > ticks)
                            {
                                break;
                            }

                            list.RemoveAt(i);
                            count--;
                            i--;
                            ThreadPool.QueueWorkItem(TimerCB, timer);
                            long period   = timer.period_ms;
                            long due_time = timer.due_time_ms;
                            bool no_more  = (period == -1 || ((period == 0 || period == Timeout.Infinite) && due_time != Timeout.Infinite));
                            if (no_more)
                            {
                                timer.next_run = Int64.MaxValue;
                            }
                            else
                            {
                                timer.next_run = GetTimeMonotonic() + TimeSpan.TicksPerMillisecond * timer.period_ms;
                                new_time.Add(timer);
                            }
                        }

                        // Reschedule timers with a new due time
                        count = new_time.Count;
                        for (i = 0; i < count; i++)
                        {
                            Timer timer = new_time [i];
                            Add(timer);
                        }
                        new_time.Clear();
                        ShrinkIfNeeded(new_time, 512);

                        // Shrink the list
                        int capacity = list.Capacity;
                        count = list.Count;
                        if (capacity > 1024 && count > 0 && (capacity / count) > 3)
                        {
                            list.Capacity = count * 2;
                        }

                        long min_next_run = Int64.MaxValue;
                        if (list.Count > 0)
                        {
                            min_next_run = ((Timer)list.GetByIndex(0)).next_run;
                        }

                        //PrintList ();
                        ms_wait = -1;
                        if (min_next_run != Int64.MaxValue)
                        {
                            long diff = (min_next_run - GetTimeMonotonic()) / TimeSpan.TicksPerMillisecond;
                            if (diff > Int32.MaxValue)
                            {
                                ms_wait = Int32.MaxValue - 1;
                            }
                            else
                            {
                                ms_wait = (int)(diff);
                                if (ms_wait < 0)
                                {
                                    ms_wait = 0;
                                }
                            }
                        }
                    }
                    // Wait until due time or a timer is changed and moves from/to the first place in the list.
                    changed.WaitOne(ms_wait);
                }
            }