Daily Task Thread - Modified TaskThread.cs

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
12 năm cách đây
I have been working on setting up "Daily Tasks" with the nop 2.1 code base ... the code in this post modifies the existing TaskThread.cs

Extra Variables

        #region Extra Thread Timing Information
        DateTime _runTimeOfDay = DateTime.MinValue;
        string _runTimeOfDayString = "";
        DateTime _nextRunTime;
        DateTime _lastRunTime;
        bool _runOnStartUp = false;
        #endregion


Updated Functions

        internal TaskThread(XmlNode node)
        {
            this._tasks = new Dictionary<string, Task>();
            this._seconds = 10 * 60;
            this._isRunning = false;

            bool _cfgSeconds = (node.Attributes["seconds"] != null);
            bool _cfgDays = (node.Attributes["days"] != null);
            bool _cfgTime = (node.Attributes["time"] != null);
            bool _cfgRunImmediately = (node.Attributes["runonstartup"] != null);

            if (_cfgSeconds)    // Original Task Behavior
            {
                if ((node.Attributes["seconds"] != null) && !int.TryParse(node.Attributes["seconds"].Value, out this._seconds))
                {
                    this._seconds = 10 * 60;
                }
                // Since seconds are setup, no need to setup the rest
                return;
            }

            // Setup days if available ...
            if (_cfgDays && !int.TryParse(node.Attributes["days"].Value, out this._days)) this._days = 0;

            // If the task thread needs to run at a specific time of day, set that up.
            if (_cfgTime)
            {
                _runTimeOfDayString = node.Attributes["time"].Value;
                if (!DateTime.TryParse(node.Attributes["time"].Value, out this._runTimeOfDay)) this._runTimeOfDay = DateTime.MinValue;
            }

            // If we dont want to wait the initial time for threading, eg. a specific time of day ... we want to run it at the soonest possible time.
            // not the next possible time.
            _runOnStartUp = node.Attributes["runonstartup"].Value == "true";
        }

        private void TimerHandler(object state)
        {
            this._timer.Change(-1, -1);
            this.Run();
            this._lastRunTime = DateTime.Now;
            this._timer.Change(this.Interval, this.Interval);
        }

        /// <summary>
        /// Gets the interval at which to run the tasks
        /// </summary>
        public int Interval
        {
            get
            {
                return _getCalculatedInterval();
            }
        }



New Functions

        private int _getCalculatedInterval()
        {
            #region If only days are set return the calculated milliseconds
            // If we are setup to run in intervals of days, calculate the days out.
            if (this._days > 0 && this._runTimeOfDay == DateTime.MinValue)
            {
                if (_runOnStartUp)
                {
                    _runOnStartUp = false;
                    return 1;
                }
                else
                {
                    return _days * 24 * 60 * 60 * 1000; // Days *  Hours * Min * Sec
                }
            }
            #endregion

            #region If the time of day is set we return the calculated the milliseconds
            // If we are setup to run at a specific time of day, calculate the duration to the next runtime
            if (this._runTimeOfDay != DateTime.MinValue)
            {
                _nextRunTime = DateTime.Now;
                // Convert the next runtime into an actual date/time -> This will be set to today, at X time.
                DateTime.TryParse(this._runTimeOfDayString, out _nextRunTime);

                #region Add Days
                // If we have days setup, use add the number of days to the next run time
                if (!_runOnStartUp)
                {
                    // Add X days, or 1 by default
                    if (this._days > 0) _nextRunTime = _nextRunTime.AddDays(this._days);
                    if (this._nextRunTime < DateTime.Now) _nextRunTime = _nextRunTime.AddDays(1);
                }
                #endregion

                #region Check to see if the run on startup needs days added to it.
                // In this case, we are are making sure that a daily interval
                if (_runOnStartUp)
                {
                    _runOnStartUp = false;
                    if (this._nextRunTime < DateTime.Now)
                    {
                        // Add X days, or 1 by default
                        if (this._days > 0) _nextRunTime = _nextRunTime.AddDays(this._days);
                        else _nextRunTime = _nextRunTime.AddDays(1);
                    }
                }
                #endregion

                // Calculate the interval until the next run
                TimeSpan futureDiff = new TimeSpan(this._nextRunTime.Ticks - DateTime.Now.Ticks);
                // make sure it is greater than 1, just incase we ate up a few thousand ticks calculating and checking.
                // ... or the machine is being hit pretty hard
                return futureDiff.TotalMilliseconds > 0 ? (int)futureDiff.TotalMilliseconds : 1;
            }
            #endregion

            // Base Case
            return _seconds * 1000;
        }

        public DateTime GetNextRunTime()
        {
            return DateTime.Now.AddMilliseconds(this.Interval);
        }

        public TimeSpan GetNextInterval()
        {
            return new TimeSpan(0, 0, 0, 0, this.Interval);
        }


Example Use of New Functionality

    <ScheduleTasks>
      <Thread days="5">
        <task />
      </Thread>
      <Thread time="12:00:00 AM">
        <task />
      </Thread>
      <Thread days="1" time="12:00:00 PM" runonstartup="true">
        <task />
      </Thread>
    </ScheduleTasks>


First Question: Does the code look ok? It is running ok for me, but want a second opinion ... maybe a little bit of optimization

Second Question: If I were to release a derivative work, that uses some nopCommerce code, what are the restrictions?
12 năm cách đây
FuriousScissors wrote:
First Question: Does the code look ok?

Yes, looks OK. You use DateTime.TryParse() without cultureinvariant parameter. It could stop working in non en-US culture. For example, in ru-RU (Russians have another datetime format)


FuriousScissors wrote:
If I were to release a derivative work, that uses some nopCommerce code, what are the restrictions?

You can find them here
12 năm cách đây
a.m. wrote:
First Question: Does the code look ok?
Yes, looks OK. You use DateTime.TryParse() without cultureinvariant parameter. It could stop working in non en-US culture. For example, in ru-RU (Russians have another datetime format)

If I were to release a derivative work, that uses some nopCommerce code, what are the restrictions?
You can find them here

Hmm, you bring up a good point. I will have to do a bit more work to make it multi-national compliant. Thank you. :)


And that specific lic. info was exactly what i was looking for.
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.