Ejemplo n.º 1
0
            static void TimerCB(object o)
            {
                Timer timer = (Timer)o;

                try {
                    timer.callback(timer.state);
                } catch {}
            }
Ejemplo n.º 2
0
            void SchedulerThread()
            {
                Thread.CurrentThread.Name = "Timer-Scheduler";
                ArrayList new_time = new ArrayList(512);

                while (true)
                {
                    long ticks = DateTime.GetTimeMonotonic();
                    lock (this) {
                        //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.QueueUserWorkItem(new WaitCallback(data => {
                                try {
                                    timer.callback(data);
                                } catch {}
                            }), timer.state);
                            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 = DateTime.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 = (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 ();
                        int ms_wait = -1;
                        if (min_next_run != Int64.MaxValue)
                        {
                            long diff = min_next_run - DateTime.GetTimeMonotonic();
                            ms_wait = (int)(diff / TimeSpan.TicksPerMillisecond);
                            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.
                        Monitor.Wait(this, ms_wait);
                    }
                }
            }