ScopedActivityListener Class
Captures the Activity instances started within the current asynchronous scope.
public sealed class ScopedActivityListener : IDisposableRemarks
An ActivityListener is global: it observes every activity created in the process. This type registers such a listener but only reports the activities started by the asynchronous flow that created it, using an AsyncLocal<T>. Disposing the instance unregisters the listener.
The membership of an activity is decided when it starts, because an activity is frequently stopped on another thread, where the asynchronous scope is no longer available. As a consequence, the activities that are still running when the listener is disposed are never reported.
The captured activities are live references, not snapshots: their tags, status and duration are only final once they are stopped.
While the listener is registered, ActivitySource.HasListeners returns true for every matching source in the whole process. The libraries that check it, such as HttpClient or ASP.NET Core, switch to their instrumented code path, so HttpClient starts sending the traceparent header for the requests made inside the scope. Use ScopedActivityListenerOptions.SourceNames to reduce the number of matching sources.
Example
using var source = new ActivitySource("Sample.ScopedActivityListener");
using var listener = new ScopedActivityListener(new() { SourceNames = ["Sample.ScopedActivityListener"] });
// Code that starts activities, such as a call to an instrumented library
using (source.StartActivity("DoWork"))
{
await Task.Delay(10);
}
var activity = Assert.Single(listener.Activities);
Assert.Equal("DoWork", activity.OperationName);
Assert.True(activity.Duration > TimeSpan.Zero);- Implements
Constructors
| Name | Description |
|---|---|
| ScopedActivityListener() | Initializes a new instance of the ScopedActivityListener class listening to every ActivitySource. |
| ScopedActivityListener(ScopedActivityListenerOptions?) | Initializes a new instance of the ScopedActivityListener class. |
ScopedActivityListener overloads
ScopedActivityListener()
ScopedActivityListener.csInitializes a new instance of the ScopedActivityListener class listening to every ActivitySource.
public ScopedActivityListener()ScopedActivityListener(ScopedActivityListenerOptions?)
ScopedActivityListener.csInitializes a new instance of the ScopedActivityListener class.
public ScopedActivityListener(ScopedActivityListenerOptions? options)Parameters
optionsScopedActivityListenerOptions?- The options of the listener, or
nullto use the default options.
Properties
| Name | Description |
|---|---|
| Activities | Gets the activities captured so far, in completion order. The collection is safe to enumerate while new activities are captured. |
Activities
ScopedActivityListener.csGets the activities captured so far, in completion order. The collection is safe to enumerate while new activities are captured.
public IReadOnlyCollection<Activity> Activities { get; }Property value
Methods
| Name | Description |
|---|---|
| Dispose() | Unregisters the listener and completes the enumerations started by ScopedActivityListener.GetActivitiesAsync. |
| GetActivitiesAsync(CancellationToken) | Streams the activities of the scope as they complete. |
Dispose()
ScopedActivityListener.csUnregisters the listener and completes the enumerations started by ScopedActivityListener.GetActivitiesAsync.
public void Dispose()GetActivitiesAsync(CancellationToken)
ScopedActivityListener.csStreams the activities of the scope as they complete.
public IAsyncEnumerable<Activity> GetActivitiesAsync(CancellationToken cancellationToken = default)Parameters
cancellationTokenCancellationToken- A token to stop the enumeration.
Returns
IAsyncEnumerable<Activity> The activities already captured, followed by the activities completing afterwards. The enumeration ends when the listener is disposed. Multiple enumerations can run concurrently, and each of them reports every activity.
Events
| Name | Description |
|---|---|
| ActivityStarted | Occurs when an activity of the scope starts. The event is raised synchronously on the thread starting the activity, so its tags, status and duration are not set yet. The exceptions thrown by the handlers are ignored to avoid breaking the observed code. |
| ActivityStopped | Occurs when an activity of the scope stops. The event is raised synchronously on the thread stopping the activity. The exceptions thrown by the handlers are ignored to avoid breaking the observed code. |
ActivityStarted
Occurs when an activity of the scope starts. The event is raised synchronously on the thread starting the activity, so its tags, status and duration are not set yet. The exceptions thrown by the handlers are ignored to avoid breaking the observed code.
public event EventHandler<ActivityEventArgs>? ActivityStartedActivityStopped
Occurs when an activity of the scope stops. The event is raised synchronously on the thread stopping the activity. The exceptions thrown by the handlers are ignored to avoid breaking the observed code.
public event EventHandler<ActivityEventArgs>? ActivityStopped