SignalR/SignalR · error · ArgumentException
Value must be greater than zero.
Error message
Value must be greater than zero.
What it means
Thrown by the HighFrequencyTimer constructor when the requested frames-per-second value is less than or equal to zero. The timer drives a fixed-interval callback loop, so a non-positive rate is mathematically invalid (it would imply an infinite or negative period).
Source
Thrown at samples/Microsoft.AspNet.SignalR.Samples/Hubs/RealtimeBroadcast/HighFrequencyTimer.cs:51
public HighFrequencyTimer(double fps, Action<long> callback)
: this(fps, callback, null, null, null)
{
}
/// <summary>
/// Creates a new instance of a high-resolution FPS timer.
/// </summary>
/// <param name="fps">The desired frame rate per second.</param>
/// <param name="callback">The callback to be invoked on each frame.</param>
/// <param name="started">The callback to be invoked when the timer enters the running state.</param>
/// <param name="stopped">The callback to be invoked when the timer enters the stopped state.</param>
/// <param name="actualFpsUpdate">The callback to invoked to receive updates of the actual frame rate.</param>
public HighFrequencyTimer(double fps, Action<long> callback, Action started, Action stopped, Action<int> actualFpsUpdate)
{
if (fps <= 0)
{
throw new ArgumentException("Value must be greater than zero.", "fps");
}
if (callback == null)
{
throw new ArgumentNullException("callback");
}
_fps = fps;
_callback = callback;
_started = started ?? (() => { });
_stopped = stopped ?? (() => { });
_actualFpsUpdate = actualFpsUpdate ?? (_ => { });
}
public bool Start()
{
// Try to move to starting state
if (Interlocked.CompareExchange(ref _state, 1, 0) != 0)View on GitHub (pinned to 693053b89a)
Solutions
- Validate fps > 0 before constructing the timer, clamping to a sane default (e.g. 30 or 60) when invalid.
- Fix the source config/UI to never offer a non-positive rate.
- Wrap the constructor call in try/catch ArgumentException to fall back to a default rate with a logged warning.
Example fix
// before var timer = new HighFrequencyTimer(fpsFromConfig, cb, started, stopped, fpsUpdate); // after var fps = fpsFromConfig > 0 ? fpsFromConfig : 30; var timer = new HighFrequencyTimer(fps, cb, started, stopped, fpsUpdate);
Defensive patterns
Strategy: validation
Validate before calling
if (fps <= 0) throw new ArgumentOutOfRangeException(nameof(fps), "fps must be positive"); // or clamp: var safeFps = fps > 0 ? fps : 30;
Try / catch
try { var t = new HighFrequencyTimer(fps, cb, s, st, u); }
catch (ArgumentException ex) when (ex.ParamName == "fps") {
logger.Warn("Invalid fps {0}, using default", fps);
timer = new HighFrequencyTimer(30, cb, s, st, u);
} Prevention
- Validate numeric config inputs at load time, not at construction time.
- Clamp UI sliders to a positive minimum.
- Unit-test the constructor boundary (0, negative, very large).
When it happens
Trigger: Constructing new HighFrequencyTimer(fps, ...) with fps <= 0. Common when fps is read from a config value, a UI slider defaulting to 0, or computed as a difference that can go negative.
Common situations: Uninitialized config field defaulting to 0; a frame-rate slider clamped at its minimum of 0; a calculation like (baseFps - overhead) producing 0 or negative under load; copy-paste from a value in different units.
Related errors
- SignalR: Invalid transport(s) specified, aborting start.
- Query string property must be either a string or object.
- Url cannot contain query string directly. Pass query string
- The hub name '{0}' is invalid.
- The buffer size '{0}' is out of range.
AI-assisted analysis of SignalR/SignalR@693053b89a (2026-08-13).
Data as JSON: /api/errors/01c7a9671bc63a8f.
Report an issue: GitHub.