tui-cs/Terminal.Gui · error · NotSupportedException

FuncTimeProvider does not support timers. Use VirtualTimePro

Error message

FuncTimeProvider does not support timers. Use VirtualTimeProvider for timer support.

What it means

This error is thrown by FuncTimeProvider.CreateTimer() because FuncTimeProvider is a lightweight test helper that only wraps a Func<DateTime> for time control and does not support timer creation. The error message directs developers to VirtualTimeProvider, which implements a full timer system for test scenarios. FuncTimeProvider is an internal class used only in tests.

Source

Thrown at Terminal.Gui/Time/FuncTimeProvider.cs:30

    ///     Initializes a new instance of the <see cref="FuncTimeProvider"/> class.
    /// </summary>
    /// <param name="timeFunc">Function that returns the current time.</param>
    public FuncTimeProvider (Func<DateTime> timeFunc) { _timeFunc = timeFunc; }

    /// <inheritdoc/>
    public DateTime Now => _timeFunc ();

    /// <inheritdoc/>
    public Task Delay (TimeSpan duration, CancellationToken cancellationToken = default)
    {
        // For test scenarios, delays complete immediately
        return Task.CompletedTask;
    }

    /// <inheritdoc/>
    public ITimer CreateTimer (TimeSpan interval, Action callback)
    {
        throw new NotSupportedException ("FuncTimeProvider does not support timers. Use VirtualTimeProvider for timer support.");
    }
}

View on GitHub (pinned to 2e47b11478)

Solutions

  1. Switch from FuncTimeProvider to VirtualTimeProvider, which supports both time control and timers.
  2. If timers are not needed in the test, mock or avoid the code path that calls CreateTimer.
  3. Review the test to confirm whether timer functionality is required; use VirtualTimeProvider if so.
  4. Check ITimeProvider documentation -- FuncTimeProvider is for time-only scenarios, VirtualTimeProvider for full timer support.

Example fix

// before -- FuncTimeProvider does not support timers
ITimeProvider timeProvider = new FuncTimeProvider(() => DateTime.Now);
// ... code under test calls timeProvider.CreateTimer(...)

// after -- use VirtualTimeProvider for timer support
VirtualTimeProvider timeProvider = new VirtualTimeProvider();
// ... code under test calls timeProvider.CreateTimer(...)
timeProvider.Advance(TimeSpan.FromSeconds(1));
Defensive patterns

Strategy: validation

Validate before calling

// Before creating FuncTimeProvider, check if timers are needed
// If so, use VirtualTimeProvider instead
ITimeProvider tp = needsTimers ? new VirtualTimeProvider() : new FuncTimeProvider(() => testTime);

Type guard

// Check if the provider supports timers before calling CreateTimer
bool SupportsTimers(ITimeProvider tp) => tp is not FuncTimeProvider;

Try / catch

try { var timer = timeProvider.CreateTimer(interval, callback); }
catch (NotSupportedException ex) { /* switch to VirtualTimeProvider */ }

Prevention

When it happens

Trigger: Thrown at FuncTimeProvider.cs:30 when CreateTimer(TimeSpan, Action) is called on a FuncTimeProvider instance. This happens when test code attempts to create a timer on a time provider that was constructed via FuncTimeProvider(Func<DateTime>) rather than VirtualTimeProvider. Any component that calls ITimeProvider.CreateTimer will trigger this.

Common situations: Writing a test that uses FuncTimeProvider (for simple time control) but the code under test schedules timers (e.g., timeout-based animations, delayed actions, periodic refresh). Mixing FuncTimeProvider with components that require timer support without realizing the limitation.

Related errors


AI-assisted analysis of tui-cs/Terminal.Gui@2e47b11478 (2026-08-13). Data as JSON: /api/errors/dc672fa4a96b49ff. Report an issue: GitHub.