Skip to content

Commit

Permalink
Added backport for Task.WaitAsync()
Browse files Browse the repository at this point in the history
  • Loading branch information
bastianeicher committed Nov 23, 2024
1 parent e0d34ab commit f84f32d
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 12 deletions.
13 changes: 1 addition & 12 deletions src/Common/Threading/ResultRacer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,18 +83,7 @@ public T GetResult()
/// Waits until at least one call to <see cref="TrySetResult"/> or <see cref="TrySetResultAsync"/> succeeded and returns its result.
/// </summary>
public async Task<T> GetResultAsync()
{
var task = _completion.Task;
#if NET
return await task.WaitAsync(cancellationToken);
#else
var cancellationCompletion = new TaskCompletionSource<bool>();
using (cancellationToken.Register(() => cancellationCompletion.SetCanceled()))
await Task.WhenAny(task, cancellationCompletion.Task);
cancellationToken.ThrowIfCancellationRequested();
return await task;
#endif
}
=> await _completion.Task.WaitAsync(cancellationToken);
}

/// <summary>
Expand Down
47 changes: 47 additions & 0 deletions src/Common/Threading/TaskExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright Bastian Eicher
// Licensed under the MIT License

#if !NET20 && !NET40
using System.Threading.Tasks;

namespace NanoByte.Common.Threading;

public static class TaskExtensions
{
/// <summary>
/// Gets a <see cref="Task"/> that will complete when <paramref name="task"/> completes or when the specified <paramref name="cancellationToken"/> has cancellation requested.
/// </summary>
/// <exception cref="OperationCanceledException">Cancellation has been requested.</exception>
public static async Task WaitAsync(this Task task, CancellationToken cancellationToken)
#if NETFRAMEWORK
{
var cancellationCompletion = new TaskCompletionSource<bool>();
var token = cancellationToken;
using (token.Register(() => cancellationCompletion.SetCanceled()))
await Task.WhenAny(task, cancellationCompletion.Task);
token.ThrowIfCancellationRequested();
await task;
}
#else
=> await task.WaitAsync(cancellationToken);
#endif

/// <summary>
/// Gets a <see cref="Task"/> that will complete when <paramref name="task"/> completes or when the specified <paramref name="cancellationToken"/> has cancellation requested.
/// </summary>
/// <exception cref="OperationCanceledException">Cancellation has been requested.</exception>
public static async Task<T> WaitAsync<T>(this Task<T> task, CancellationToken cancellationToken)
#if NETFRAMEWORK
{
var cancellationCompletion = new TaskCompletionSource<bool>();
var token = cancellationToken;
using (token.Register(() => cancellationCompletion.SetCanceled()))
await Task.WhenAny(task, cancellationCompletion.Task);
token.ThrowIfCancellationRequested();
return await task;
}
#else
=> await task.WaitAsync(cancellationToken);
#endif
}
#endif

0 comments on commit f84f32d

Please sign in to comment.