DomEventLoop Class
The window event loop (https://html.spec.whatwg.org/multipage/webappapis.html#window-event-loop) of a browsing context group: each top-level BrowsingContext has its own event loop, shared by its nested browsing contexts (BrowsingContext.EventLoop). It runs the tasks and the microtasks of their documents (load events, timers, mutation observers, slotchange events, scripts...). The documents that are not associated with a browsing context (e.g. a document parsed by HtmlDocumentParser) have no event loop: the tasks and the microtasks of their nodes are not queued. The host drives the loop: call DomEventLoop.PerformMicrotaskCheckpoint, DomEventLoop.RunUntilIdle or DomEventLoop.RunUntilIdleAsync. Tasks can be queued from any thread (e.g. when an asynchronous operation completes); they run on the thread that runs the loop. When a browsing context has a ScriptEngine, the microtasks are queued in the job queue of the engine, so that they run in order with the promise jobs.
public sealed class DomEventLoopRemarks
In the specification, the agents of a browsing context group are keyed by site, and each agent has its own event loop. The library runs all the documents of a browsing context group on a single thread, so a single event loop runs the tasks of all its agents in one of the orders allowed by the specification.
Properties
| Name | Description |
|---|---|
| AutoPerformMicrotaskCheckpoint | Gets or sets whether queued microtasks run synchronously at the end of each DOM operation that queued them. |
| HasPendingOperations | Gets whether asynchronous operations are in progress (e.g. documents loaded by BrowsingContextOptions.DocumentLoader). They queue a task when they complete. |
| HasPendingWork | Gets whether there are pending tasks or microtasks. |
| HasRunningWorkers | Gets whether a worker created by the documents of the event loop (or by its workers) has a task to run, or runs a task that is not waiting for a synchronous operation: a host that advances a fake clock waits for the workers before advancing it. |
| IsDisposed | Gets whether the event loop was disposed with its browsing context (BrowsingContext.Dispose): the tasks, the microtasks and the timers queued afterwards are ignored. |
| MicrotaskQueueOverride | Gets or sets a function that queues microtasks in another queue (for instance the job queue of a JavaScript engine), so that microtasks queued by the DOM and by scripts are interleaved in order. |
| TimeProvider | Gets or sets the clock of the timers (setTimeout(), requestAnimationFrame(), AbortSignal.timeout()...) and of performance.now(). The default is TimeProvider.System. A browsing context created with BrowsingContextOptions.TimeProvider sets it. Use a fake clock (e.g. FakeTimeProvider) to run the timers without waiting. |
| TimerQueueOverride | Gets or sets a function that schedules the timers of the DOM (e.g. AbortSignal.timeout()) in the host's own timer queue, so they are ordered with the other timers of the host. |
| WorkSignal | Gets or sets the callback invoked when work arrives, from any thread: a task is queued (e.g. by an asynchronous operation that completes on another thread, such as a document loaded by BrowsingContextOptions.DocumentLoader), a timer is queued, or an asynchronous operation ends. A host that runs the event loop on its own thread uses it to wake up and call DomEventLoop.RunTask and DomEventLoop.PromoteDueTimers. The callback must not run the event loop itself. |
| WorkerActivity | Gets a value that changes each time a worker created by the documents of the event loop (or by its workers) stops running (see DomEventLoop.HasRunningWorkers): it ran a task, or its task waits for a synchronous operation. A worker may run between two reads of DomEventLoop.HasRunningWorkers (e.g. its timer becomes due when another thread reads the clock) and add a timer or queue a task meanwhile: a host that advances a fake clock reads this value before computing the next timer, and does not advance the clock if it changed. |
AutoPerformMicrotaskCheckpoint
DomEventLoop.csHasPendingOperations
DomEventLoop.csGets whether asynchronous operations are in progress (e.g. documents loaded by BrowsingContextOptions.DocumentLoader). They queue a task when they complete.
public bool HasPendingOperations { get; }Property value
HasPendingWork
DomEventLoop.csHasRunningWorkers
DomEventLoop.Workers.csGets whether a worker created by the documents of the event loop (or by its workers) has a task to run, or runs a task that is not waiting for a synchronous operation: a host that advances a fake clock waits for the workers before advancing it.
public bool HasRunningWorkers { get; }Property value
IsDisposed
DomEventLoop.csGets whether the event loop was disposed with its browsing context (BrowsingContext.Dispose): the tasks, the microtasks and the timers queued afterwards are ignored.
public bool IsDisposed { get; }Property value
MicrotaskQueueOverride
DomEventLoop.cs- Obsolete: Use BrowsingContextOptions.ScriptEngine: the microtasks are queued in the job queue of the script engine.
Gets or sets a function that queues microtasks in another queue (for instance the job queue of a JavaScript engine), so that microtasks queued by the DOM and by scripts are interleaved in order.
[Obsolete("Use BrowsingContextOptions.ScriptEngine: the microtasks are queued in the job queue of the script engine.")]
public Action<Action>? MicrotaskQueueOverride { get; set; }Property value
TimeProvider
DomEventLoop.csGets or sets the clock of the timers (setTimeout(), requestAnimationFrame(), AbortSignal.timeout()...) and of performance.now(). The default is TimeProvider.System. A browsing context created with BrowsingContextOptions.TimeProvider sets it. Use a fake clock (e.g. FakeTimeProvider) to run the timers without waiting.
public TimeProvider TimeProvider { get; set; }Property value
TimerQueueOverride
DomEventLoop.cs- Obsolete: Use BrowsingContextOptions.TimeProvider or DomEventLoop.TimeProvider: the timers of the windows are implemented by the library.
Gets or sets a function that schedules the timers of the DOM (e.g. AbortSignal.timeout()) in the host's own timer queue, so they are ordered with the other timers of the host.
[Obsolete("Use BrowsingContextOptions.TimeProvider or DomEventLoop.TimeProvider: the timers of the windows are implemented by the library.")]
public Action<TimeSpan, Action>? TimerQueueOverride { get; set; }Property value
WorkSignal
DomEventLoop.csGets or sets the callback invoked when work arrives, from any thread: a task is queued (e.g. by an asynchronous operation that completes on another thread, such as a document loaded by BrowsingContextOptions.DocumentLoader), a timer is queued, or an asynchronous operation ends. A host that runs the event loop on its own thread uses it to wake up and call DomEventLoop.RunTask and DomEventLoop.PromoteDueTimers. The callback must not run the event loop itself.
public Action? WorkSignal { get; set; }Property value
WorkerActivity
DomEventLoop.Workers.csGets a value that changes each time a worker created by the documents of the event loop (or by its workers) stops running (see DomEventLoop.HasRunningWorkers): it ran a task, or its task waits for a synchronous operation. A worker may run between two reads of DomEventLoop.HasRunningWorkers (e.g. its timer becomes due when another thread reads the clock) and add a timer or queue a task meanwhile: a host that advances a fake clock reads this value before computing the next timer, and does not advance the clock if it changed.
public long WorkerActivity { get; }Property value
Methods
| Name | Description |
|---|---|
| PerformMicrotaskCheckpoint() | https://html.spec.whatwg.org/multipage/webappapis.html#perform-a-microtask-checkpoint |
| PromoteDueTimers() | Moves the due timers to the task queue. Returns the time until the next timer, or null when there is none. The timers of the workers created by the documents of the event loop are included in the result (they run on the threads of the workers), so that a host that advances a fake clock to the next timer also runs the timers of the workers. |
| QueueMicrotask(Action) | https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-microtask |
| QueueTask(Action) | Queues a task (https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-task). |
| QueueTimer(TimeSpan, Action) | Queues a task after a delay (e.g. setTimeout() or AbortSignal.timeout()), measured with DomEventLoop.TimeProvider. The timers are moved to the task queue once they are due (DomEventLoop.PromoteDueTimers, DomEventLoop.RunUntilIdle). The timers that are due at the same time run in the order they were queued. |
| RunTask() | Runs one task, followed by a microtask checkpoint. Returns false when there is no task. The tasks run in the order they were queued, except the tasks of the schedulers (Scheduler.PostTask, Scheduler.Yield), which run in the order of their priorities: see DomEventLoop.SelectNextSchedulerTaskQueue. When no task is queued, an idle period runs the idle callbacks of the windows (Window.RequestIdleCallback). |
| RunUntilIdle() | Runs the microtasks and the tasks until both queues are empty. |
| RunUntilIdleAsync(CancellationToken) | Runs the microtasks and the tasks until both queues are empty and no asynchronous operation is in progress (e.g. the documents loaded by BrowsingContextOptions.DocumentLoader). |
| WaitForNextTimerAsync(CancellationToken) | Waits until the next timer is due, using DomEventLoop.TimeProvider (e.g. until a fake clock is advanced), and moves it to the task queue. Returns false when there is no timer and no task. For instance, to run the tasks and the timers until there is nothing left: do { await eventLoop.RunUntilIdleAsync(); } while (await eventLoop.WaitForNextTimerAsync()); |
PerformMicrotaskCheckpoint()
DomEventLoop.cshttps://html.spec.whatwg.org/multipage/webappapis.html#perform-a-microtask-checkpoint
public void PerformMicrotaskCheckpoint()PromoteDueTimers()
DomEventLoop.csMoves the due timers to the task queue. Returns the time until the next timer, or null when there is none. The timers of the workers created by the documents of the event loop are included in the result (they run on the threads of the workers), so that a host that advances a fake clock to the next timer also runs the timers of the workers.
public TimeSpan? PromoteDueTimers()Returns
QueueMicrotask(Action)
DomEventLoop.csQueueTask(Action)
DomEventLoop.csQueueTimer(TimeSpan, Action)
DomEventLoop.csQueues a task after a delay (e.g. setTimeout() or AbortSignal.timeout()), measured with DomEventLoop.TimeProvider. The timers are moved to the task queue once they are due (DomEventLoop.PromoteDueTimers, DomEventLoop.RunUntilIdle). The timers that are due at the same time run in the order they were queued.
RunTask()
DomEventLoop.csRuns one task, followed by a microtask checkpoint. Returns false when there is no task. The tasks run in the order they were queued, except the tasks of the schedulers (Scheduler.PostTask, Scheduler.Yield), which run in the order of their priorities: see DomEventLoop.SelectNextSchedulerTaskQueue. When no task is queued, an idle period runs the idle callbacks of the windows (Window.RequestIdleCallback).
public bool RunTask()Returns
RunUntilIdle()
DomEventLoop.csRuns the microtasks and the tasks until both queues are empty.
public void RunUntilIdle()RunUntilIdleAsync(CancellationToken)
DomEventLoop.csRuns the microtasks and the tasks until both queues are empty and no asynchronous operation is in progress (e.g. the documents loaded by BrowsingContextOptions.DocumentLoader).
net10.0
public Task RunUntilIdleAsync(CancellationToken cancellationToken = default)net11.0
public Task RunUntilIdleAsync(CancellationToken cancellationToken = default)WaitForNextTimerAsync(CancellationToken)
DomEventLoop.csWaits until the next timer is due, using DomEventLoop.TimeProvider (e.g. until a fake clock is advanced), and moves it to the task queue. Returns false when there is no timer and no task. For instance, to run the tasks and the timers until there is nothing left: do { await eventLoop.RunUntilIdleAsync(); } while (await eventLoop.WaitForNextTimerAsync());
net10.0
public Task<bool> WaitForNextTimerAsync(CancellationToken cancellationToken = default)net11.0
public Task<bool> WaitForNextTimerAsync(CancellationToken cancellationToken = default)