dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'taskFactory')
Error message
Value cannot be null. (Parameter 'taskFactory')
What it means
The TaskPoolScheduler constructor throws ArgumentNullException when the TaskFactory is null. The scheduler relies on the factory to start tasks for each scheduled work item; a null factory would break every Schedule call, so Rx validates eagerly. TaskPoolScheduler.Default is the ready-made instance using TaskScheduler.Default.
Solutions
- Pass a valid TaskFactory, e.g. new TaskFactory() or new TaskFactory(cancellationToken, TaskCreationOptions, TaskContinuationOptions, taskScheduler).
- Use TaskPoolScheduler.Default if no custom factory is required.
- Fix the DI/config wiring that produced a null TaskFactory.
Example fix
// before
var sched = new TaskPoolScheduler(_taskFactory); // null
// after
var sched = _taskFactory != null
? new TaskPoolScheduler(_taskFactory)
: TaskPoolScheduler.Default; Defensive patterns
Strategy: validation
Validate before calling
if (taskFactory == null) taskFactory = TaskPoolScheduler.Default; // or new TaskFactory()
Type guard
bool hasFactory = taskFactory is not null;
Try / catch
try { var sched = new TaskPoolScheduler(taskFactory); }
catch (ArgumentNullException) { var sched = TaskPoolScheduler.Default; } Prevention
- Use TaskPoolScheduler.Default unless a custom factory is truly needed
- Initialize TaskFactory fields at declaration or via constructor injection
- Verify DI registrations supply a TaskFactory instance
When it happens
Trigger: new TaskPoolScheduler((TaskFactory)null), usually a TaskFactory field/property that was never initialized or a DI registration that yielded null.
Common situations: Configuring a custom TaskFactory (e.g. with a specific TaskScheduler or CancellationToken) where the configuration step silently failed; refactoring that removed factory initialization.
Related errors
- Value cannot be null. (Parameter 'action')
- action (Parameter 'action')
- action (Value cannot be null)
- ArgumentNullException: action
- ArgumentNullException (default message: Value cannot be…
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/2c6f81175a93c378.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Concurrency/TaskPoolScheduler.cs:191
public void Dispose()
{
_cancel.Dispose();
}
public bool IsDisposed => _cancel.IsDisposed;
}
private static readonly Lazy<TaskPoolScheduler> LazyInstance = new(static () => new TaskPoolScheduler(new TaskFactory(TaskScheduler.Default)));
private readonly TaskFactory _taskFactory;
/// <summary>
/// Creates an object that schedules units of work using the provided <see cref="TaskFactory"/>.
/// </summary>
/// <param name="taskFactory">Task factory used to create tasks to run units of work.</param>
/// <exception cref="ArgumentNullException"><paramref name="taskFactory"/> is <c>null</c>.</exception>
public TaskPoolScheduler(TaskFactory taskFactory)
{
_taskFactory = taskFactory ?? throw new ArgumentNullException(nameof(taskFactory));
}
/// <summary>
/// Gets an instance of this scheduler that uses the default <see cref="TaskScheduler"/>.
/// </summary>
public static TaskPoolScheduler Default => LazyInstance.Value;
/// <summary>
/// Schedules an action to be executed.
/// </summary>
/// <typeparam name="TState">The type of the state passed to the scheduled action.</typeparam>
/// <param name="state">State passed to the action to be executed.</param>
/// <param name="action">Action to be executed.</param>
/// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
/// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
public override IDisposable Schedule<TState>(TState state, Func<IScheduler, TState, IDisposable> action)
{
if (action == null)View on GitHub (pinned to 94b5d5ab91)