Table of Contents

Class ObservableEvent<T>

Namespace
WebDriverBiDi
Assembly
WebDriverBiDi.dll

Implementation of a subject in the Observer pattern for events. It can optionally be limited to a specific number of observers.

public class ObservableEvent<T> where T : WebDriverBiDiEventArgs

Type Parameters

T

The type of event arguments containing information about the observable event.

Inheritance
ObservableEvent<T>
Derived
Inherited Members
Extension Methods

Remarks

Thread Safety: This class is thread-safe. AddObserver(Func<T, Task>, ObservableEventHandlerOptions, string), RemoveObserver(string), NotifyObserversAsync(T), and CurrentObserverCount may be called concurrently from multiple threads. Observer registration and removal are serialized via an internal lock, which each publishes a new array of the observers in notification order. Notification reads that array without taking the lock and iterates it to completion, so a long-running handler neither blocks registration nor is disturbed by one, and an observer added or removed while an event is being dispatched takes effect from the next event. See EventObserver<T> for thread-safety of the capture methods on observers.

Constructors

ObservableEvent(string, uint)

Initializes a new instance of the ObservableEvent<T> class.

protected ObservableEvent(string eventName, uint maxObserverCount)

Parameters

eventName string

The name of the event.

maxObserverCount uint

The maximum number of observers that may observe this event.

Properties

CurrentObserverCount

Gets the current number of observers, including data collectors, that are observing this event.

public int CurrentObserverCount { get; }

Property Value

int

EventName

Gets the name of this observable event.

public string EventName { get; }

Property Value

string

MaxObserverCount

Gets the maximum number of observers, including data collectors, that may observe this event. A value of zero (0) indicates an unlimited number of observers.

public uint MaxObserverCount { get; }

Property Value

uint

TimeProvider

Gets or sets the TimeProvider used for time comparisons in observers.

protected TimeProvider TimeProvider { get; set; }

Property Value

TimeProvider

Methods

AddDataCollector(Func<T, bool>?, string)

Adds a data collector that accumulates event data for on-demand inspection rather than reacting to each event as it arrives. Each data collector counts as one observer against the event's MaxObserverCount.

public EventDataCollector<T> AddDataCollector(Func<T, bool>? filter = null, string description = "")

Parameters

filter Func<T, bool>

An optional function that filters the data collected by this data collector.

description string

An optional human-readable description for this data collector.

Returns

EventDataCollector<T>

An EventDataCollector<T> that queues each event raised on this observable. Call GetCollectedEventData() to drain the queue. Dispose the collector when collection is no longer needed.

Examples

await using EventDataCollector<BeforeRequestSentEventArgs> collector =
    driver.Network.OnBeforeRequestSent.AddDataCollector();

await driver.BrowsingContext.NavigateAsync(navParams);

IReadOnlyList<BeforeRequestSentEventArgs> requests = collector.GetCollectedEventData();
Console.WriteLine($"Page made {requests.Count} network requests");

Exceptions

WebDriverBiDiException

Thrown when the user attempts to add more observers than this event allows.

AddObserver(Action<T>, ObservableEventHandlerOptions, string)

Adds a function to observe the event that takes an argument of type T and returns void. It will be wrapped in a Task so that it can be awaited.

public EventObserver<T> AddObserver(Action<T> handler, ObservableEventHandlerOptions handlerOptions = ObservableEventHandlerOptions.RunHandlerSynchronously, string description = "")

Parameters

handler Action<T>

An action that handles the observed event.

handlerOptions ObservableEventHandlerOptions

The options for executing the handler. Defaults to RunHandlerSynchronously, meaning the action runs inline on the thread dispatching the event and notification waits for it to return. With RunHandlerAsynchronously the whole action is queued to the thread pool via Run(Action), so none of it runs on the dispatching thread; use that option for actions that perform I/O, long-running work, or execute driver commands.

description string

An optional description for this observer.

Returns

EventObserver<T>

An observer for this observable event.

Exceptions

WebDriverBiDiException

Thrown when the user attempts to add more observers than this event allows.

ArgumentNullException

Thrown when a null handler is passed.

AddObserver(Func<T, Task>, ObservableEventHandlerOptions, string)

Adds a function to observe the event that takes an argument of type T and returns a Task.

public EventObserver<T> AddObserver(Func<T, Task> handler, ObservableEventHandlerOptions handlerOptions = ObservableEventHandlerOptions.RunHandlerSynchronously, string description = "")

Parameters

handler Func<T, Task>

A function returning a Task that handles the observed event.

handlerOptions ObservableEventHandlerOptions

The options for executing the handler. Defaults to RunHandlerSynchronously, meaning notification awaits the returned Task before continuing. With RunHandlerAsynchronously the returned Task is not awaited, but the handler is still invoked on the thread dispatching the event: in an async lambda everything up to the first await that does not complete synchronously runs on that thread, and a non-async handler that does its work before returning a completed task is not offloaded at all. Handlers that perform I/O, long-running work, or execute driver commands should use this option and be written as async handlers that await before doing the heavy work (for example await Task.Yield()), or wrap it in Task.Run. See RunHandlerAsynchronously.

description string

An optional description for this observer.

Returns

EventObserver<T>

An observer for this observable event.

Examples

// Synchronous handler (default) - for quick in-memory work
driver.Log.OnEntryAdded.AddObserver(e => Console.WriteLine(e.Text));

// Async handler with RunHandlerAsynchronously - for I/O or long-running work
driver.Network.OnBeforeRequestSent.AddObserver(
    async (e) => await SaveRequestToFileAsync(e.Request),
    ObservableEventHandlerOptions.RunHandlerAsynchronously);

Exceptions

WebDriverBiDiException

Thrown when the user attempts to add more observers than this event allows.

ArgumentNullException

Thrown when a null handler is passed.

NotifyObserversAsync(T)

Asynchronously notifies observers when this observable event occurs. Each observer is notified independently; an exception thrown by one observer does not prevent subsequent observers from being notified.

protected Task NotifyObserversAsync(T notifyData)

Parameters

notifyData T

The data of the event.

Returns

Task

The task object representing the asynchronous operation.

Remarks

When an observer-error reporter is installed, as it is for every event the library creates, a failing observer reports its own failure through it, identifying itself, and this method does not throw for it. Without a reporter, a failure of a synchronously-run observer propagates to the caller: if exactly one observer throws, the original exception is rethrown; if multiple observers throw, an AggregateException containing all caught exceptions is thrown after all observers have been notified. A failure of an asynchronously-run observer never propagates to the caller.

Exceptions

AggregateException

Thrown, when no observer-error reporter is installed, if multiple observer handlers throw an exception.

RemoveObserver(string)

Removes a handler for this observable event.

public void RemoveObserver(string observerId)

Parameters

observerId string

The ID of the handler handling the event.

SetObserverErrorReporter(Func<EventObserverErrorInfo, Task>)

Sets the internal reporter used to surface observer failures that occur after the handler has already returned to the caller.

protected void SetObserverErrorReporter(Func<EventObserverErrorInfo, Task> reporter)

Parameters

reporter Func<EventObserverErrorInfo, Task>

The reporter callback.

ToString()

Returns a string that represents the current object.

public override string ToString()

Returns

string

A string that represents the current object.