Table of Contents

Class TaskExtensions

Namespace
Plugin.BaseTypeExtensions
Assembly
Plugin.BaseTypeExtensions.dll

Provides extension methods for working with Task and Task<TResult> objects, including optional timeout patterns.

public static class TaskExtensions
Inheritance
TaskExtensions
Inherited Members

Methods

StartAndForget(Task, Action<Exception>)

Executes the task asynchronously in a fire-and-forget manner without waiting for its completion. This method is intended for scenarios where you want to start a background operation without blocking the caller, and you need to handle any exceptions that may occur during execution.

public static void StartAndForget(this Task task, Action<Exception> onException)

Parameters

task Task

The task to execute. Must not be null.

onException Action<Exception>

An action that will be invoked if the task throws an exception. The exception will be passed as a parameter to this action. This handler is called on the thread pool context (due to ConfigureAwait(false)). Must not be null.

Examples

// Example: Start a background logging operation
LogAsync(message).StartAndForget(ex =>
    Console.WriteLine($"Logging failed: {ex.Message}"));

// Example: Send telemetry without blocking
SendTelemetryAsync(data).StartAndForget(ex =>
    _logger.LogError(ex, "Telemetry failed"));

Remarks

This method is useful for starting background operations where you don't need to await the result, but you want to ensure that exceptions are handled gracefully rather than being silently swallowed or causing unobserved task exceptions.

The method returns immediately after starting the task execution. The task runs on the thread pool context (ConfigureAwait(false) is used), ensuring it doesn't capture the synchronization context.

Common use cases include:

  • Logging operations that shouldn't block the main flow
  • Fire-and-forget notifications or telemetry
  • Background cleanup or maintenance tasks

Warning: Because this is an async void method, exceptions thrown before the first await cannot be caught by the caller. Always ensure that the task parameter is valid before calling this method.

Exceptions

ArgumentNullException

Thrown when task or onException is null.

StartAndForget(Task, TaskCompletionSource)

Executes the task asynchronously in a fire-and-forget manner without waiting for its completion, and signals the completion or failure through a TaskCompletionSource. This method is intended for scenarios where you want to start a background operation without blocking the caller, and you need to track its completion status via a TaskCompletionSource.

public static void StartAndForget(this Task task, TaskCompletionSource completionSource)

Parameters

task Task

The task to execute. Must not be null.

completionSource TaskCompletionSource

A TaskCompletionSource that will be completed when the task finishes. If the task completes successfully, TrySetResult() is called. If the task throws an exception, TrySetException(Exception) is called with that exception. Must not be null.

Examples

// Example: Track completion of a background operation
var tcs = new TaskCompletionSource();
BackgroundWorkAsync().StartAndForget(tcs);
// Later, you can await tcs.Task to know when it completed
await tcs.Task;

// Example: Coordinate multiple background operations
var operations = new[] { Op1Async(), Op2Async(), Op3Async() };
var completionSources = operations.Select(_ => new TaskCompletionSource()).ToArray();
for (int i = 0; i < operations.Length; i++)
{
    operations[i].StartAndForget(completionSources[i]);
}
await Task.WhenAll(completionSources.Select(tcs => tcs.Task));

Remarks

This method is useful for starting background operations where you don't need to await the result immediately, but you want to track completion status through a TaskCompletionSource. This allows you to observe the completion or failure of the background operation at a later time.

The method returns immediately after starting the task execution. The task runs on the thread pool context (ConfigureAwait(false) is used), ensuring it doesn't capture the synchronization context.

Common use cases include:

  • Starting background operations that need to signal completion to waiting code
  • Fire-and-forget operations where you want to track success/failure externally
  • Coordinating multiple background tasks through their completion sources

Warning: Because this is an async void method, exceptions thrown before the first await cannot be caught by the caller. Always ensure that the task parameter is valid before calling this method.

Exceptions

ArgumentNullException

Thrown when task or completionSource is null.

StartAndForget(ValueTask, Action<Exception>)

Executes the ValueTask asynchronously in a fire-and-forget manner without waiting for its completion. This method is intended for scenarios where you want to start a background operation without blocking the caller, and you need to handle any exceptions that may occur during execution.

public static void StartAndForget(this ValueTask valueTask, Action<Exception> onException)

Parameters

valueTask ValueTask

The ValueTask to execute. Must not be null.

onException Action<Exception>

An action that will be invoked if the task throws an exception. The exception will be passed as a parameter to this action. This handler is called on the thread pool context (due to ConfigureAwait(false)). Must not be null.

Examples

// Example: Start a background logging operation
LogAsync(message).StartAndForget(ex =>
    Console.WriteLine($"Logging failed: {ex.Message}"));

// Example: Send telemetry without blocking
SendTelemetryAsync(data).StartAndForget(ex =>
    _logger.LogError(ex, "Telemetry failed"));

Remarks

This method is useful for starting background operations where you don't need to await the result, but you want to ensure that exceptions are handled gracefully rather than being silently swallowed or causing unobserved task exceptions.

The method returns immediately after starting the task execution. The task runs on the thread pool context (ConfigureAwait(false) is used), ensuring it doesn't capture the synchronization context.

Common use cases include:

  • Logging operations that shouldn't block the main flow
  • Fire-and-forget notifications or telemetry
  • Background cleanup or maintenance tasks

Warning: Because this is an async void method, exceptions thrown before the first await cannot be caught by the caller. Always ensure that the valueTask parameter is valid before calling this method.

Exceptions

ArgumentNullException

Thrown when onException is null.

StartAndForget(ValueTask, TaskCompletionSource)

Executes the ValueTask asynchronously in a fire-and-forget manner without waiting for its completion, and signals the completion or failure through a TaskCompletionSource. This method is intended for scenarios where you want to start a background operation without blocking the caller, and you need to track its completion status via a TaskCompletionSource.

public static void StartAndForget(this ValueTask valueTask, TaskCompletionSource completionSource)

Parameters

valueTask ValueTask

The ValueTask to execute. Must not be null.

completionSource TaskCompletionSource

A TaskCompletionSource that will be completed when the task finishes. If the task completes successfully, TrySetResult() is called. If the task throws an exception, TrySetException(Exception) is called with that exception. Must not be null.

Examples

// Example: Track completion of a background operation
var tcs = new TaskCompletionSource();
BackgroundWorkAsync().StartAndForget(tcs);
// Later, you can await tcs.Task to know when it completed
await tcs.Task;

// Example: Coordinate multiple background operations
var operations = new[] { Op1Async(), Op2Async(), Op3Async() };
var completionSources = operations.Select(_ => new TaskCompletionSource()).ToArray();
for (int i = 0; i < operations.Length; i++)
{
    operations[i].StartAndForget(completionSources[i]);
}
await Task.WhenAll(completionSources.Select(tcs => tcs.Task));

Remarks

This method is useful for starting background operations where you don't need to await the result immediately, but you want to track completion status through a TaskCompletionSource. This allows you to observe the completion or failure of the background operation at a later time.

The method returns immediately after starting the task execution. The task runs on the thread pool context (ConfigureAwait(false) is used), ensuring it doesn't capture the synchronization context.

Common use cases include:

  • Starting background operations that need to signal completion to waiting code
  • Fire-and-forget operations where you want to track success/failure externally
  • Coordinating multiple background tasks through their completion sources

Warning: Because this is an async void method, exceptions thrown before the first await cannot be caught by the caller. Always ensure that the valueTask parameter is valid before calling this method.

Exceptions

ArgumentNullException

Thrown when completionSource is null.

WaitBetterAsync(Task, TimeSpan?, CancellationToken)

Waits for the task to complete within an optional timeout period.

public static Task WaitBetterAsync(this Task task, TimeSpan? timeout, CancellationToken cancellationToken = default)

Parameters

task Task

The task to wait for.

timeout TimeSpan?

The optional timeout duration. If null, zero, or negative, the method returns the original task (no timeout).

cancellationToken CancellationToken

A cancellation token to observe while waiting for the task to complete.

Returns

Task

If timeout is null, zero, or negative: returns the original task. Otherwise: returns a task that completes when the original task completes or when the timeout expires.

Remarks

This method provides a convenient way to add optional timeouts to any task. When no timeout is needed, simply pass null and the original task is returned unchanged. This avoids the overhead of timeout monitoring when it's not required.

Exceptions

ArgumentNullException

Thrown when task is null.

TimeoutException

Thrown when the task doesn't complete within the specified timeout.

OperationCanceledException

Thrown when the operation is canceled via the cancellationToken.

WaitBetterAsync<T>(Task<T>, TimeSpan?, CancellationToken)

Waits for the task to complete within an optional timeout period.

public static Task<T> WaitBetterAsync<T>(this Task<T> task, TimeSpan? timeout, CancellationToken cancellationToken = default)

Parameters

task Task<T>

The task to wait for.

timeout TimeSpan?

The optional timeout duration. If null, zero, or negative, the method returns the original task (no timeout).

cancellationToken CancellationToken

A cancellation token to observe while waiting for the task to complete.

Returns

Task<T>

If timeout is null, zero, or negative: returns the original task. Otherwise: returns a task that completes when the original task completes or when the timeout expires.

Type Parameters

T

The type of the task result.

Remarks

This method provides a convenient way to add optional timeouts to any task. When no timeout is needed, simply pass null and the original task is returned unchanged. This avoids the overhead of timeout monitoring when it's not required.

Exceptions

ArgumentNullException

Thrown when task is null.

TimeoutException

Thrown when the task doesn't complete within the specified timeout.

OperationCanceledException

Thrown when the operation is canceled via the cancellationToken.