Пример #1
0
            /// <summary>
            /// Run this Timers event loop in its own Thread.
            /// </summary>
            public void Run()
            {
                while (true)
                {
                    TimerTask task;
                    lock (this.syncRoot)
                    {
                        // need to check cancelled inside the synchronized block
                        if (cancelled)
                        {
                            return;
                        }

                        if (tasks.IsEmpty())
                        {
                            if (finished)
                            {
                                return;
                            }

                            // no tasks scheduled -- sleep until any task appear
                            try
                            {
                                Monitor.Wait(this.syncRoot);
                            }
                            catch (ThreadInterruptedException)
                            {
                            }
                            continue;
                        }

                        DateTime currentTime = DateTime.Now;

                        task = tasks.Minimum();
                        TimeSpan timeToSleep;

                        lock (task.syncRoot)
                        {
                            if (task.cancelled)
                            {
                                tasks.Delete(0);
                                continue;
                            }

                            // check the time to sleep for the first task scheduled
                            timeToSleep = task.when - currentTime;
                        }

                        if (timeToSleep.CompareTo(TimeSpan.Zero) > 0)
                        {
                            // sleep!
                            try
                            {
                                Monitor.Wait(this.syncRoot, timeToSleep);
                            }
                            catch (ThreadInterruptedException)
                            {
                            }
                            continue;
                        }

                        // no sleep is necessary before launching the task
                        lock (task.syncRoot)
                        {
                            int pos = 0;
                            if (tasks.Minimum().when != task.when)
                            {
                                pos = tasks.GetTask(task);
                            }
                            if (task.cancelled)
                            {
                                tasks.Delete(tasks.GetTask(task));
                                continue;
                            }

                            // set time to schedule
                            task.ScheduledTime = task.when;

                            // remove task from queue
                            tasks.Delete(pos);

                            // set when the next task should be launched
                            if (task.period.CompareTo(TimeSpan.Zero) >= 0)
                            {
                                // this is a repeating task,
                                if (task.fixedRate)
                                {
                                    // task is scheduled at fixed rate
                                    task.when = task.when + task.period;
                                }
                                else
                                {
                                    // task is scheduled at fixed delay
                                    task.when = DateTime.Now + task.period;
                                }

                                // insert this task into queue
                                InsertTask(task);
                            }
                            else
                            {
                                task.when = DateTime.MinValue;
                            }
                        }
                    }

                    bool taskCompletedNormally = false;
                    try
                    {
                        task.Run();
                        taskCompletedNormally = true;
                    }
                    finally
                    {
                        if (!taskCompletedNormally)
                        {
                            lock (this)
                            {
                                cancelled = true;
                            }
                        }
                    }
                }
            }