Table of Contents

Class StandaloneSchedulerFactory

Namespace
Quartz
Assembly
Quartz.dll

A scheduler factory that owns the container its scheduler was built from.

public sealed class StandaloneSchedulerFactory : ISchedulerFactory, IDisposable, IAsyncDisposable
Inheritance
StandaloneSchedulerFactory
Implements
Inherited Members
Extension Methods

Remarks

This is what Build() returns. A scheduler built without an application-supplied container has one of its own, and something has to own it — so the factory does. Disposing the factory shuts down every scheduler that container built and then disposes the container, which is what the hosted service does for an application that has one.

The shutdown does not wait for running jobs, which is the default WaitForJobsToComplete and Shutdown(bool, CancellationToken) both carry — two Quartz-owned shutdown paths that disagreed about whether a job gets to finish would be a trap. A caller that wants to wait says so and then disposes: await scheduler.Shutdown(waitForJobsToComplete: true) leaves the factory with nothing left to shut down, so the two compose.

Disposal is asynchronous where the caller can await it: shutting a scheduler down is asynchronous work, and Dispose() can only block on it. Prefer await using over using.

Disposing twice does nothing the second time, and disposing a factory whose scheduler was never asked for does nothing at all — a scheduler is never built merely to be torn down.

A caller that never disposes behaves exactly as one did with the process-lifetime scheduler of earlier versions: the scheduler runs until the process ends.

Methods

Dispose()

Shuts down the schedulers this factory's container built, then disposes the container.

public void Dispose()

Remarks

Blocking, because a synchronous door onto asynchronous work can do nothing else, and the alternative is what this used to do: return promptly with the scheduler still running. It also cannot be a bare container disposal, synchronous or not — a container that handed its IScheduler to anything holds a singleton implementing only IAsyncDisposable, and disposing such a container synchronously throws.

DisposeAsync()

Shuts down the schedulers this factory's container built, then disposes the container.

public ValueTask DisposeAsync()

Returns

ValueTask

Remarks

Blocking, because a synchronous door onto asynchronous work can do nothing else, and the alternative is what this used to do: return promptly with the scheduler still running. It also cannot be a bare container disposal, synchronous or not — a container that handed its IScheduler to anything holds a singleton implementing only IAsyncDisposable, and disposing such a container synchronously throws.

GetAllSchedulers(CancellationToken)

Returns handles to every scheduler in the container this factory belongs to.

public ValueTask<List<IScheduler>> GetAllSchedulers(CancellationToken cancellationToken = default)

Parameters

cancellationToken CancellationToken

Returns

ValueTask<List<IScheduler>>

Remarks

A scheduler is only in the repository of the container that built it, so a factory lists its own container's schedulers and nobody else's.

GetScheduler(CancellationToken)

Returns a client-usable handle to the IScheduler this factory produces, building it if it has not been built yet.

public ValueTask<IScheduler> GetScheduler(CancellationToken cancellationToken = default)

Parameters

cancellationToken CancellationToken

Returns

ValueTask<IScheduler>

Remarks

Never returns null: a factory is configured to produce exactly one scheduler, so either it can be built or the attempt throws.

LookupScheduler(string, CancellationToken)

Finds the scheduler with the given name, or null when this container has none.

public ValueTask<IScheduler?> LookupScheduler(string schedulerName, CancellationToken cancellationToken = default)

Parameters

schedulerName string
cancellationToken CancellationToken

Returns

ValueTask<IScheduler>

Remarks

This is a lookup, which is why it is named for one and why it is nullable while GetScheduler(CancellationToken) is not: any name other than this factory's own belongs to a scheduler somebody else registered, and it may not exist. The comparison ignores case, because that is how the repository indexes names.

A name the container registered is built on demand, whether or not it is this factory's own: what makes a scheduler exist is the registration, so "give me tenant acme" does not depend on whether something else happened to resolve it first. A name added at runtime with ISchedulerRuntime is found while it is alive and not rebuilt after it has been shut down — it has no registration to be rebuilt from, and adding it again is that interface's.

Only schedulers from the same container are visible. A scheduler built by a QuartzSchedulerBuilder of its own is not in this container's repository and is reported as absent.