dotnet/reactive · critical · NotSupportedException

The scheduler service

Error message

The scheduler service '{0}' is not available.

What it means

Scheduler.Initialize resolves an IScheduler from the platform enlightenment provider by service name; when the provider returns no implementation it throws NotSupportedException with 'The scheduler service "{0}" is not available.' This is how Scheduler.ThreadPool, NewThread and TaskPool lazily bind to the platform at first access.

Solutions

  1. Reference System.Reactive.PlatformServices so the default provider registers scheduler services
  2. If using a custom PlatformEnlightenmentProvider, ensure GetService<IScheduler>(name) returns implementations for "ThreadPool", "NewThread", "TaskPool"
  3. Use Scheduler.Default / immediate schedulers as a fallback instead of the missing service

Example fix

// before
class MyProvider : IPlatformEnlightenmentProvider
{
    public T GetService<T>(object[] args) where T : class => null; // scheduler services missing
}
// after
public T GetService<T>(object[] args) where T : class
{
    if (typeof(T) == typeof(IScheduler)) return new MyScheduler() as T;
    return new DefaultPlatformEnlightenmentProvider().GetService<T>(args);
}
Defensive patterns

Strategy: fallback

Validate before calling

var sched = PlatformEnlightenmentProvider.Current.GetService<IScheduler>("ThreadPool");
if (sched == null) sched = new DefaultSchedulerShim();

Type guard

static bool SchedulerServiceAvailable<T>() where T : class => PlatformEnlightenmentProvider.Current.GetService<T>("ThreadPool") != null;

Try / catch

try { sched = Scheduler.TaskPool; }
catch (NotSupportedException ex)
{
    // fall back to default scheduler or log environment misconfiguration
    sched = Scheduler.Default;
}

Prevention

When it happens

Trigger: Accessing Scheduler.ThreadPool, Scheduler.NewThread or Scheduler.TaskPool in an environment where the platform enlightenment provider was not configured (e.g. custom PlatformEnlightenmentProvider without scheduler services, trimmed/AOT app missing the System.Reactive.PlatformServices registration).

Common situations: Replacing the default enlightenment provider with a custom one that omits IScheduler services; unit-test hosts that stub the provider; missing platform services package in some targets.

Related errors


AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15). Data as JSON: /api/errors/1967516b01127a7b. Report an issue: GitHub.

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Concurrency/Scheduler.cs:90

        /// <summary>
        /// Gets a scheduler that schedules work on a new thread using default thread creation options.
        /// </summary>
        [Obsolete(Constants_Core.ObsoleteSchedulerNewthread)]
        public static IScheduler NewThread => _newThread.Value;

        private static readonly Lazy<IScheduler> _taskPool = new(static () => Initialize("TaskPool"));

        /// <summary>
        /// Gets a scheduler that schedules work on Task Parallel Library (TPL) task pool using the default TaskScheduler.
        /// </summary>
        [Obsolete(Constants_Core.ObsoleteSchedulerTaskpool)]
        public static IScheduler TaskPool => _taskPool.Value;

        private static IScheduler Initialize(string name)
        {
            return PlatformEnlightenmentProvider.Current.GetService<IScheduler>(name)
                ?? throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, Strings_Core.CANT_OBTAIN_SCHEDULER, name));
        }
    }
}

View on GitHub (pinned to 94b5d5ab91)