Skip to content

Instantly share code, notes, and snippets.

@coenm
Last active September 30, 2022 06:53
Show Gist options
  • Select an option

  • Save coenm/e0cc18f346eac9331353d679289ad7aa to your computer and use it in GitHub Desktop.

Select an option

Save coenm/e0cc18f346eac9331353d679289ad7aa to your computer and use it in GitHub Desktop.
Add a timeout to task
namespace TaskUtils;
using System;
using System.Threading;
using System.Threading.Tasks;
public static class TaskExtensions
{
/// <summary>
/// See for more information:
/// http://stackoverflow.com/questions/14524209/what-is-the-correct-way-to-cancel-an-async-operation-that-doesnt-accept-a-cance/14524565#14524565
/// </summary>
public static async Task<T> WithWaitCancellation<T>(this Task<T> task, CancellationToken cancellationToken)
{
var tcs = new TaskCompletionSource<bool>();
// Register with the cancellation token.
await using (cancellationToken.Register(s => ((TaskCompletionSource<bool>)s).TrySetResult(true), tcs))
{
// If the task waited on is the cancellation token...
if (task != await Task.WhenAny(task, tcs.Task).ConfigureAwait(false))
throw new OperationCanceledException(cancellationToken);
}
// Wait for one or the other to complete.
return await task.ConfigureAwait(false);
}
public static async Task WithWaitCancellation(this Task task, CancellationToken cancellationToken)
{
var tcs = new TaskCompletionSource<bool>();
// Register with the cancellation token.
await using (cancellationToken.Register(s => ((TaskCompletionSource<bool>)s).TrySetResult(true), tcs))
{
// If the task waited on is the cancellation token...
if (task != await Task.WhenAny(task, tcs.Task).ConfigureAwait(false))
throw new OperationCanceledException(cancellationToken);
}
// Wait for one or the other to complete.
await task.ConfigureAwait(false);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment