Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -435,4 +435,7 @@ doc/plans/
*speedscope*.json

# Dotnet trace files
*.nettrace
*.nettrace

# Git worktrees
.worktrees/
25 changes: 9 additions & 16 deletions TUnit.Engine/Helpers/TimeoutHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,22 +59,15 @@ public static async Task<T> ExecuteWithTimeoutAsync<T>(
// Fast path: no timeout specified
if (!timeout.HasValue)
{
var task = taskFactory(cancellationToken);

// If the token can't be cancelled, just await directly (avoid allocations)
if (!cancellationToken.CanBeCanceled)
{
return await task.ConfigureAwait(false);
}

// Race against cancellation - TrySetCanceled makes the TCS throw OperationCanceledException when awaited
var tcs = new TaskCompletionSource<T>(TaskCreationOptions.RunContinuationsAsynchronously);
using var reg = cancellationToken.Register(
static state => ((TaskCompletionSource<T>)state!).TrySetCanceled(),
tcs);

// await await: first gets winning task, then awaits it (propagates result or exception)
return await await Task.WhenAny(task, tcs.Task).ConfigureAwait(false);
#if NET6_0_OR_GREATER
// Use WaitAsync to stop waiting immediately on cancellation while avoiding
// TCS + CancellationTokenRegistration allocations. The task still runs to completion
// but we return control to the caller immediately.
return await taskFactory(cancellationToken).WaitAsync(cancellationToken).ConfigureAwait(false);
#else
// On older frameworks, rely on cooperative cancellation
return await taskFactory(cancellationToken).ConfigureAwait(false);
#endif
}

// Timeout path: create linked token so task can observe both timeout and external cancellation.
Expand Down
Loading