792 lines · 30.1 KB · C#
RawDownload
//******************************************************************************************************//  ScheduleManager.cs - Gbtc////  Copyright © 2012, Grid Protection Alliance.  All Rights Reserved.////  Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See//  the NOTICE file distributed with this work for additional information regarding copyright ownership.//  The GPA licenses this file to you under the MIT License (MIT), the "License"; you may//  not use this file except in compliance with the License. You may obtain a copy of the License at:////      http://www.opensource.org/licenses/MIT////  Unless agreed to in writing, the subject software distributed under the License is distributed on an//  "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the//  License for the specific language governing permissions and limitations.////  Code Modification History://  ----------------------------------------------------------------------------------------------------//  08/01/2006 - Pinal C. Patel//       Original version of source code generated.//  04/23/2007 - Pinal C. Patel//       Made the schedules dictionary case-insensitive.//  04/24/2007 - Pinal C. Patel//       Implemented the IPersistSettings and ISupportInitialize interfaces.//  05/02/2007 - Pinal C. Patel//       Converted schedules to a list instead of a dictionary.//  11/30/2007 - Pinal C. Patel//       Modified the "design time" check in EndInit() method to use LicenseManager.UsageMode property//       instead of DesignMode property as the former is more accurate than the latter.//       Modified the Stop() method to avoid a  null reference exception that was most likely causing//       the IDE of the component's consumer to crash in design-mode.//  09/19/2008 - J. Ritchie Carroll//       Convert to C#.//  11/04/2008 - Pinal C. Patel//       Edited code comments.//  06/18/2009 - Pinal C. Patel//       Fixed the implementation of Enabled property.//  09/14/2009 - Stephen C. Wills//       Added new header and license agreement.//  06/21/2010 - Stephen C. Wills//       Modified code to avoid calls to abort the m_startTimerThread.//  07/02/2010 - J. Ritchie Carroll//       Fixed an issue related to accessing a disposed timer.//  08/04/2010 - Pinal C. Patel//       Fixed an issue with NullReferenceException being encountered when ScheduleManager object is //       disposed before it successfully starts up (StartTimer() method).//  12/14/2012 - Starlynn Danyelle Gilliam//       Modified Header.////****************************************************************************************************** using System;using System.Collections.Generic;using System.ComponentModel;using System.Configuration;using System.Drawing;using System.Text;using System.Threading;using System.Timers;using GSF.Collections;using GSF.Configuration;using Timer = System.Timers.Timer; namespace GSF.Scheduling{    /// <summary>    /// Monitors multiple <see cref="Schedule"/> at an interval of one minute to check if they are due.    /// </summary>    /// <example>    /// This example shows how to use the <see cref="ScheduleManager"/> component:    /// <code>    /// using System;    /// using GSF;    /// using GSF.Scheduling;    ///     /// class Program    /// {    ///     static void Main(string[] args)    ///     {    ///         ScheduleManager scheduler = new ScheduleManager();    ///         scheduler.Initialize();    ///         // Add event handlers.    ///         scheduler.Starting += scheduler_Starting;    ///         scheduler.Started += scheduler_Started;    ///         scheduler.ScheduleDue += scheduler_ScheduleDue;    ///         // Add test schedules.    ///         scheduler.AddSchedule("Run.Notepad", "* * * * *");    ///         scheduler.AddSchedule("Run.Explorer", "* * * * *");    ///         // Start the scheduler.    ///         scheduler.Start();    ///     ///         Console.ReadLine();    ///     }    ///     ///     static void scheduler_Started(object sender, EventArgs e)    ///     {    ///         Console.WriteLine("Scheduler has started successfully.");    ///     }    ///     ///     static void scheduler_Starting(object sender, EventArgs e)    ///     {    ///         Console.WriteLine("Scheduler is waiting to be started.");    ///     }    ///     ///     static void scheduler_ScheduleDue(object sender, EventArgs<![CDATA[<]]>Schedule<![CDATA[>]]> e)    ///     {    ///         Console.WriteLine(string.Format("{0} schedule is due for processing.", e.Argument.Name));    ///     }    /// }    /// </code>    /// </example>    /// <seealso cref="Schedule"/>    [ToolboxBitmap(typeof(ScheduleManager))]    public class ScheduleManager : Component, ISupportLifecycle, ISupportInitialize, IProvideStatus, IPersistSettings    {        #region [ Members ]         // Constants         /// <summary>        /// Specifies the default value for the <see cref="PersistSettings"/> property.        /// </summary>        public const bool DefaultPersistSettings = false;         /// <summary>        /// Specifies the default value for the <see cref="SettingsCategory"/> property.        /// </summary>        public const string DefaultSettingsCategory = "ScheduleManager";         /// <summary>        /// Number of milliseconds between timer ticks.        /// </summary>        private const int TimerInterval = 60000;         // Events         /// <summary>        /// Occurs while the <see cref="ScheduleManager"/> is waiting to start at the top of the minute.        /// </summary>        [Category("State"),        Description("Occurs while the ScheduleManager is waiting to start at the top of the minute.")]        public event EventHandler Starting;         /// <summary>        /// Occurs when the <see cref="ScheduleManager"/> has started at the top of the minute.        /// </summary>        [Category("State"),        Description("Occurs when the ScheduleManager has started at the top of the minute.")]        public event EventHandler Started;         /// <summary>        /// Occurs asynchronously when a <see cref="Schedule"/> is due according to the rule specified for it.        /// </summary>        /// <remarks>        /// <see cref="EventArgs{T}.Argument"/> is the <see cref="Schedule"/> that is due.        /// </remarks>        [Category("Schedules"),        Description("Occurs asynchronously when a Schedule is due according to the rule specified for it.")]        public event EventHandler<EventArgs<Schedule>> ScheduleDue;         /// <summary>        /// Occurs when the a particular <see cref="Schedule"/> is being checked to see if it is due.        /// </summary>        /// <remarks>        /// <see cref="EventArgs{T}.Argument"/> is the <see cref="Schedule"/> that is being checked to see if it is due.        /// </remarks>        [Category("Schedules"),        Description("Occurs when the a particular Schedule is being checked to see if it is due.")]        public event EventHandler<EventArgs<Schedule>> ScheduleDueCheck;         // Fields        private bool m_persistSettings;        private string m_settingsCategory;        private readonly List<Schedule> m_schedules;        private Timer m_timer;#if ThreadTracking        private ManagedThread m_startTimerThread;#else        private Thread m_startTimerThread;#endif        private bool m_disposed;        private bool m_initialized;         #endregion         #region [ Constructors ]         /// <summary>        /// Initializes a new instance of the <see cref="ScheduleManager"/> class.        /// </summary>        public ScheduleManager()        {            m_persistSettings = DefaultPersistSettings;            m_settingsCategory = DefaultSettingsCategory;            m_schedules = new List<Schedule>();        }         /// <summary>        /// Initializes a new instance of the <see cref="ScheduleManager"/> class.        /// </summary>        /// <param name="container"><see cref="IContainer"/> object that contains the <see cref="ScheduleManager"/>.</param>        public ScheduleManager(IContainer container)            : this()        {            if ((object)container != null)                container.Add(this);        }         #endregion         #region [ Properties ]         /// <summary>        /// Gets or sets a boolean value that indicates whether the settings of <see cref="ScheduleManager"/> object are         /// to be saved to the config file.        /// </summary>        [Category("Persistence"),        DefaultValue(DefaultPersistSettings),        Description("Indicates whether the settings of ScheduleManager object are to be saved to the config file.")]        public bool PersistSettings        {            get            {                return m_persistSettings;            }            set            {                m_persistSettings = value;            }        }         /// <summary>        /// Gets or sets the category under which the settings of <see cref="ScheduleManager"/> object are to be saved        /// to the config file if the <see cref="PersistSettings"/> property is set to true.        /// </summary>        /// <exception cref="ArgumentNullException">The value being assigned is null or empty string.</exception>        [Category("Persistence"),        DefaultValue(DefaultSettingsCategory),        Description("Category under which the settings of ScheduleManager object are to be saved to the config file if the PersistSettings property is set to true.")]        public string SettingsCategory        {            get            {                return m_settingsCategory;            }            set            {                if (string.IsNullOrEmpty(value))                    throw new ArgumentNullException(nameof(value));                 m_settingsCategory = value;            }        }         /// <summary>        /// Gets a list of all <see cref="Schedule"/> monitored by the <see cref="ScheduleManager"/> object.        /// </summary>        /// <remarks>        /// Thread-safety Warning: Due to the asynchronous nature of <see cref="ScheduleManager"/>, a lock must be         /// obtained on <see cref="Schedules"/> before accessing it.        /// </remarks>        [Category("Settings"),        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),        Description("Gets a list of all Schedule monitored by the ScheduleManager object.")]        public List<Schedule> Schedules        {            get            {                return m_schedules;            }        }         /// <summary>        /// Gets a boolean value that indicates whether the <see cref="ScheduleManager"/> is running.        /// </summary>        [Browsable(false)]        public bool IsRunning        {            get            {                if ((object)m_timer != null)                    return m_timer.Enabled;                 return false;            }        }         /// <summary>        /// Gets or sets a boolean value that indicates whether the <see cref="ScheduleManager"/> object is currently enabled.        /// </summary>        /// <remarks>        /// <see cref="Enabled"/> property is not be set by user-code directly.        /// </remarks>        [Browsable(false),        EditorBrowsable(EditorBrowsableState.Never),        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]        public bool Enabled        {            get            {                return IsRunning;            }            set            {                if (value && !Enabled)                    Start();                else if (!value && Enabled)                    Stop();            }        }         /// <summary>        /// Gets a flag that indicates whether the object has been disposed.        /// </summary>        [Browsable(false),        EditorBrowsable(EditorBrowsableState.Never),        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]        public bool IsDisposed        {            get            {                return m_disposed;            }        }         /// <summary>        /// Gets the unique identifier of the <see cref="ScheduleManager"/> object.        /// </summary>        [Browsable(false)]        public string Name        {            get            {                return m_settingsCategory;            }        }         /// <summary>        /// Gets the descriptive status of the <see cref="ScheduleManager"/> object.        /// </summary>        [Browsable(false)]        public string Status        {            get            {                StringBuilder status = new StringBuilder();                status.Append("       Number of schedules: ");                status.Append(m_schedules.Count);                status.AppendLine();                lock (m_schedules)                {                    foreach (Schedule schedule in m_schedules)                    {                        status.AppendLine();                        status.Append(schedule.Status);                    }                }                 return status.ToString();            }        }         #endregion         #region [ Methods ]         /// <summary>        /// Initializes the <see cref="ScheduleManager"/> object.        /// </summary>        /// <remarks>        /// <see cref="Initialize()"/> is to be called by user-code directly only if the <see cref="ScheduleManager"/>         /// object is not consumed through the designer surface of the IDE.        /// </remarks>        public void Initialize()        {            if (!m_initialized)            {                LoadSettings();         // Load settings from the config file.                m_initialized = true;   // Initialize only once.            }        }         /// <summary>        /// Performs necessary operations before the <see cref="ScheduleManager"/> object properties are initialized.        /// </summary>        /// <remarks>        /// <see cref="BeginInit()"/> should never be called by user-code directly. This method exists solely for use         /// by the designer if the <see cref="ScheduleManager"/> object is consumed through the designer surface of the IDE.        /// </remarks>        [EditorBrowsable(EditorBrowsableState.Never)]        public void BeginInit()        {            if (!DesignMode)            {                try                {                    // Nothing needs to be done before component is initialized.                }                catch (Exception)                {                    // Prevent the IDE from crashing when component is in design mode.                }            }        }         /// <summary>        /// Performs necessary operations after the <see cref="ScheduleManager"/> object properties are initialized.        /// </summary>        /// <remarks>        /// <see cref="EndInit()"/> should never be called by user-code directly. This method exists solely for use         /// by the designer if the <see cref="ScheduleManager"/> object is consumed through the designer surface of the IDE.        /// </remarks>        [EditorBrowsable(EditorBrowsableState.Never)]        public void EndInit()        {            if (!DesignMode)            {                try                {                    Initialize();                }                catch (Exception)                {                    // Prevent the IDE from crashing when component is in design mode.                }            }        }         /// <summary>        /// Saves settings for the <see cref="ScheduleManager"/> object to the config file if the <see cref="PersistSettings"/>         /// property is set to true.        /// </summary>        /// <exception cref="ConfigurationErrorsException"><see cref="SettingsCategory"/> has a value of null or empty string.</exception>        public void SaveSettings()        {            if (m_persistSettings)            {                // Ensure that settings category is specified.                if (string.IsNullOrEmpty(m_settingsCategory))                    throw new ConfigurationErrorsException("SettingsCategory property has not been set");                 // Save settings under the specified category.                ConfigurationFile config = ConfigurationFile.Current;                CategorizedSettingsElementCollection settings = config.Settings[m_settingsCategory];                 settings.Clear();                 lock (m_schedules)                {                    foreach (Schedule schedule in m_schedules)                    {                        if (schedule.UseLocalTime)                            settings[schedule.Name, true].Update(string.Format("rule={0}; useLocalTime={1}", schedule.Rule, schedule.UseLocalTime), schedule.Description);                        else                            settings[schedule.Name, true].Update(schedule.Rule, schedule.Description);                    }                }                 config.Save();            }        }         /// <summary>        /// Loads saved settings for the <see cref="ScheduleManager"/> object from the config file if the <see cref="PersistSettings"/>         /// property is set to true.        /// </summary>        /// <exception cref="ConfigurationErrorsException"><see cref="SettingsCategory"/> has a value of null or empty string.</exception>        public void LoadSettings()        {            if (m_persistSettings)            {                // Ensure that settings category is specified.                if (string.IsNullOrEmpty(m_settingsCategory))                    throw new ConfigurationErrorsException("SettingsCategory property has not been set");                 // Load settings from the specified category.                ConfigurationFile config = ConfigurationFile.Current;                CategorizedSettingsElementCollection settings = config.Settings[m_settingsCategory];                 foreach (CategorizedSettingsElement setting in settings)                {                    if ((object)setting != null && !string.IsNullOrWhiteSpace(setting.Name))                    {                        string value = setting.Value.ToNonNullNorWhiteSpace("* * * * *");                        Dictionary<string, string> lookup = value.ParseKeyValuePairs();                         // Add the schedule if it doesn't exist or update it otherwise with data from the config file.                        Schedule existingSchedule = FindSchedule(setting.Name);                         if ((object)existingSchedule == null)                        {                            // Schedule doesn't exist, so we'll add it.                            lock (m_schedules)                            {                                m_schedules.Add(new Schedule(setting.Name, lookup.GetOrDefault("rule", key => value), setting.Description.ToNonNullString(), lookup.GetOrDefault("useLocalTime").ParseBoolean()));                            }                        }                        else                        {                            // Schedule exists, so we'll update it.

Lines 1–500 of 792.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t