예제 #1
0
 /// <summary>
 /// Updates the current trigger timer using the specified trigger.
 /// </summary>
 /// <param name="trigger">The trigger information.</param>
 private void OnUpdateTimer(CrawlerTrigger trigger)
 {
     // Synchronize access.
     lock (this.sync)
     {
         // Get the current time;
         DateTime now = DateTime.Now;
         // Set the current trigger.
         this.timerTrigger = trigger;
         // If the trigger timestamp does not meet the minimum trigger delay.
         if (now + this.minimumTriggerDelay > trigger.Timestamp)
         {
             // Disable the timer.
             this.timer.Change(Timeout.Infinite, Timeout.Infinite);
             // Execute the trigger now on the thread pool.
             ThreadPool.QueueUserWorkItem(this.OnTrigger);
         }
         else
         {
             // Update the timer.
             this.timer.Change((long)trigger.Timestamp.Subtract(now).TotalMilliseconds, Timeout.Infinite);
         }
     }
 }
예제 #2
0
        /// <summary>
        /// An event handler called when the trigger timer expires.
        /// </summary>
        /// <param name="state">The state.</param>
        private void OnTrigger(object state)
        {
            // The current trigger.
            KeyValuePair<DateTime, CrawlerTrigger> first;

            // Synchronize access.
            lock (this.sync)
            {
                // If the trigger list is empty, do nothing.
                if (this.timeline.Count == 0) return;

                // Get the first trigger.
                first = this.timeline.First();

                // Check the timer has been triggered for the current timer trigger. Otherwise, return.
                if (!object.ReferenceEquals(this.timerTrigger, first.Value)) return;

                // Remove the first trigger from the list.
                if (!this.timeline.Remove(first.Key)) throw new InvalidOperationException("Internal task scheduler exception: cannot remove an existing trigger.");

                // Set the current timer trigger to null.
                this.timerTrigger = null;

                // If the trigger list is not empty.
                if (this.timeline.Count > 0)
                {
                    // Get the next trigger.
                    KeyValuePair<DateTime, CrawlerTrigger> next = this.timeline.First();
                    // Update the timer.
                    this.OnUpdateTimer(next.Value);
                }
            }

            // Execute the current trigger.
            first.Value.Execute();
        }
예제 #3
0
        /// <summary>
        /// Removes a trigger from the tasks timeline.
        /// </summary>
        /// <param name="trigger">The trigger.</param>
        public void RemoveTrigger(CrawlerTrigger trigger)
        {
            // Synchronize access.
            lock (this.sync)
            {
                // Check the trigger list is not empty.
                if (this.timeline.Count == 0) throw new InvalidOperationException("Internal task scheduler exception: cannot remove a trigger because the trigger list is empty.");

                // Get the first trigger.
                KeyValuePair<DateTime, CrawlerTrigger> first = this.timeline.First();

                // Remove the trigger.
                if (!this.timeline.Remove(trigger.Timestamp)) throw new InvalidOperationException("Internal task schedule exception: cannot remove a trigger because it could not be found.");

                // If the trigger is the first trigger.
                if (object.ReferenceEquals(first.Value, trigger))
                {
                    // If the trigger list is empty.
                    if (this.timeline.Count == 0)
                    {
                        // Disable the timer.
                        this.timer.Change(Timeout.Infinite, Timeout.Infinite);
                    }
                    else
                    {
                        // Get the next trigger.
                        KeyValuePair<DateTime, CrawlerTrigger> next = this.timeline.First();
                        // Update the timer.
                        this.OnUpdateTimer(next.Value);
                    }
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Adds the specified trigger to the timeline.
        /// </summary>
        /// <param name="trigger">The trigger.</param>
        /// <param name="timestamp">The timeline timestamp.</param>
        private void OnAddTriggerSafe(CrawlerTrigger trigger, out DateTime timestamp)
        {
            // Synchronize access.
            lock (this.sync)
            {
                // Get the trigger timestamp.
                timestamp = trigger.Timestamp;
                // If the timestamp exists.
                while (this.timeline.ContainsKey(timestamp))
                {
                    // Increment the timestamp.
                    timestamp.AddTicks(1);
                }

                // Add the trigger.
                this.timeline.Add(timestamp, trigger);
            }
        }
예제 #5
0
 /// <summary>
 /// Adds a new trigger to the tasks timeline.
 /// </summary>
 /// <param name="trigger">The trigger.</param>
 /// <param name="timestamp">The timeline timestamp.</param>
 public void AddTrigger(CrawlerTrigger trigger, out DateTime timestamp)
 {
     // Synchronize access.
     lock (this.sync)
     {
         // If the timeline is empty.
         if (this.timeline.Count == 0)
         {
             // Add the trigger to the timeline.
             this.OnAddTriggerSafe(trigger, out timestamp);
             // Update the timer.
             this.OnUpdateTimer(trigger);
         }
         else
         {
             // The first trigger.
             KeyValuePair<DateTime, CrawlerTrigger> first = this.timeline.First();
             // Add the trigger to the triggers list.
             this.OnAddTriggerSafe(trigger, out timestamp);
             // If the timestamp of the current schedule is smaller than the timestamp of the first schedule.
             if (trigger.Timestamp < first.Key)
             {
                 // Update the timer.
                 this.OnUpdateTimer(trigger);
             }
         }
     }
 }