{"record":{"id":"0b445cfa5bbbe1b5","repo":"dotnet/reactive","slug":"specified-argument-was-out-of-the-range-of-valid-values-0b445c","errorCode":null,"errorMessage":"Specified argument was out of the range of valid values. (Parameter 'period')","messagePattern":"Specified argument was out of the range of valid values\\. \\(Parameter 'period'\\)","errorType":"validation","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Platforms/Desktop/Concurrency/ControlScheduler.cs","lineNumber":164,"sourceCode":"\n        /// <summary>\n        /// Schedules a periodic piece of work on the message loop associated with the control, using a Windows Forms Timer object.\n        /// </summary>\n        /// <typeparam name=\"TState\">The type of the state passed to the scheduled action.</typeparam>\n        /// <param name=\"state\">Initial state passed to the action upon the first iteration.</param>\n        /// <param name=\"period\">Period for running the work periodically.</param>\n        /// <param name=\"action\">Action to be executed, potentially updating the state.</param>\n        /// <returns>The disposable object used to cancel the scheduled recurring action (best effort).</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"action\"/> is null.</exception>\n        /// <exception cref=\"ArgumentOutOfRangeException\"><paramref name=\"period\"/> is less than one millisecond.</exception>\n        public IDisposable SchedulePeriodic<TState>(TState state, TimeSpan period, Func<TState, TState> action)\n        {\n            //\n            // Threshold derived from Interval property setter in ndp\\fx\\src\\winforms\\managed\\system\\winforms\\Timer.cs.\n            //\n            if (period.TotalMilliseconds < 1)\n            {\n                throw new ArgumentOutOfRangeException(nameof(period));\n            }\n\n            if (action == null)\n            {\n                throw new ArgumentNullException(nameof(action));\n            }\n\n            var createTimer = new Func<IScheduler, TState, IDisposable>((scheduler1, state1) =>\n            {\n                var timer = new System.Windows.Forms.Timer();\n\n                timer.Tick += (s, e) =>\n                {\n                    if (!_control.IsDisposed)\n                    {\n                        state1 = action(state1);\n                    }\n                };","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Platforms/Desktop/Concurrency/ControlScheduler.cs#L146-L182","documentation":"ControlScheduler.SchedulePeriodic requires a period of at least 1 millisecond because it is backed by a System.Windows.Forms.Timer, whose Interval property has the same lower bound (threshold taken from the WinForms Timer setter). Periods of TimeSpan.Zero, negative values, or sub-millisecond fractions throw ArgumentOutOfRangeException with Parameter 'period'.","triggerScenarios":"scheduler.SchedulePeriodic(state, TimeSpan.Zero, action), negative TimeSpan, or TimeSpan.FromTicks(<10000) / TimeSpan.FromMilliseconds(0.5) — anything with TotalMilliseconds < 1.","commonSituations":"Computing the interval from a config value of 0 interpreted as 'as fast as possible'; dividing a TimeSpan and rounding down to zero; porting code from another scheduler (e.g. DefaultScheduler) that accepts zero or negative periods as immediate/tight loops.","solutions":["Clamp the period to at least 1 ms: period = period < TimeSpan.FromMilliseconds(1) ? TimeSpan.FromMilliseconds(1) : period.","If a tight/immediate loop is intended, use a different scheduler (Scheduler.Default / TaskPool) instead of ControlScheduler.","Validate configured interval values at startup and fail fast with a clear message."],"exampleFix":"// before\nscheduler.SchedulePeriodic(state, TimeSpan.FromMilliseconds(config.IntervalMs), tick); // 0 → throws\n// after\nvar period = TimeSpan.FromMilliseconds(Math.Max(config.IntervalMs, 1));\nscheduler.SchedulePeriodic(state, period, tick);","handlingStrategy":"validation","validationCode":"var min = TimeSpan.FromMilliseconds(1);\nif (period < min) period = min;\nscheduler.SchedulePeriodic(state, period, action);","typeGuard":"static bool IsValidPeriod(TimeSpan p) => p.TotalMilliseconds >= 1;","tryCatchPattern":"try { scheduler.SchedulePeriodic(state, period, action); } catch (ArgumentOutOfRangeException ex) when (ex.ParamName == \"period\") { /* clamp to 1ms and retry */ }","preventionTips":["Clamp configured intervals to >= 1ms for WinForms Timer-based scheduling","Remember ControlScheduler uses System.Windows.Forms.Timer (1ms floor)","Use Scheduler.Default for sub-millisecond or zero periods"],"tags":["dotnet","winforms","argument-out-of-range","timer"],"backgroundTag":"argument-out-of-range","analyzedSha":"94b5d5ab912789f5abe9a72138a25bbd716fe59c","analyzedAt":"2026-09-15T02:26:24.759Z","contentChangedAt":"2026-09-15T02:26:24.759Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}