aspnetboilerplate/aspnetboilerplate · error · AbpException

Period should be set before starting the timer!

Error message

Period should be set before starting the timer!

What it means

The synchronous AbpTimer.Start() checks that the Period property is positive before starting the underlying timer; if Period <= 0 it throws AbpException. The timer cannot schedule callbacks with an invalid period, so the library fails fast. This is a programming/configuration error, not a runtime environment issue.

Solutions

  1. Assign a positive Period (in milliseconds) before calling Start()
  2. Validate config-sourced period values before constructing the timer
  3. Prefer deriving from AbpWorker / AbpBackgroundWorkerBase which handles timer setup

Example fix

// before
var timer = new AbpTimer { RunOnStart = false };
timer.Start(); // throws
// after
var timer = new AbpTimer { Period = 5000, RunOnStart = false };
timer.Start();
Defensive patterns

Strategy: validation

Validate before calling

if (timer.Period <= 0) throw new InvalidOperationException("Set Period before starting AbpTimer");
timer.Start();

Type guard

bool CanStart(AbpTimer t) => t != null && t.Period > 0;

Prevention

When it happens

Trigger: Calling AbpTimer.Start() when Period was never assigned or assigned 0/negative. Common in custom background jobs or when porting code that previously used a different timer.

Common situations: Background worker classes in Abp modules that start timers in PostInitialize without setting Period; configuration values read as 0 because of a missing appSettings key.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of aspnetboilerplate/aspnetboilerplate@2323c13a15 (2026-09-08). Data as JSON: /api/errors/7ae5a1fbe5208d1a. Report an issue: GitHub.

Appendix: source

Thrown at src/Abp/Threading/Timers/AbpTimer.cs:72

        /// Creates a new Timer.
        /// </summary>
        /// <param name="period">Task period of timer (as milliseconds)</param>
        /// <param name="runOnStart">Indicates whether timer raises Elapsed event on Start method of Timer for once</param>
        public AbpTimer(int period, bool runOnStart = false)
            : this()
        {
            Period = period;
            RunOnStart = runOnStart;
        }

        /// <summary>
        /// Starts the timer.
        /// </summary>
        public override void Start()
        {
            if (Period <= 0)
            {
                throw new AbpException("Period should be set before starting the timer!");
            }

            base.Start();

            _running = true;
            _taskTimer.Change(RunOnStart ? 0 : Period, Timeout.Infinite);
        }

        /// <summary>
        /// Stops the timer.
        /// </summary>
        public override void Stop()
        {
            lock (_taskTimer)
            {
                _running = false;
                _taskTimer.Change(Timeout.Infinite, Timeout.Infinite);
            }

View on GitHub (pinned to 2323c13a15)