using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Npgsql
{
internal static class TaskExtensions
{
///
/// Utility that simplifies awaiting a task with a timeout. If the given task does not
/// complete within , a is thrown.
///
/// The task to be awaited
/// How much time to allow to complete before throwing a
/// An awaitable task that represents the original task plus the timeout
internal static async Task WithTimeout(this Task task, NpgsqlTimeout timeout)
{
var timeoutTask = Task.Delay(timeout.TimeLeft);
if (task != await Task.WhenAny(task, timeoutTask))
throw new TimeoutException();
return await task;
}
///
/// Utility that simplifies awaiting a task with a timeout. If the given task does not
/// complete within , a is thrown.
///
/// The task to be awaited
/// How much time to allow to complete before throwing a
/// An awaitable task that represents the original task plus the timeout
internal static async Task WithTimeout(this Task task, NpgsqlTimeout timeout)
{
var timeoutTask = Task.Delay(timeout.TimeLeft);
if (task != await Task.WhenAny(task, timeoutTask))
throw new TimeoutException();
await task;
}
///
/// Allows you to cancel awaiting for a non-cancellable task.
///
///
/// Read http://blogs.msdn.com/b/pfxteam/archive/2012/10/05/how-do-i-cancel-non-cancelable-async-operations.aspx
/// and be very careful with this.
///
internal static async Task WithCancellation(this Task task, CancellationToken cancellationToken)
{
var tcs = new TaskCompletionSource();
using (cancellationToken.Register(
s => ((TaskCompletionSource)s).TrySetResult(true), tcs))
if (task != await Task.WhenAny(task, tcs.Task))
throw new TaskCanceledException(task);
return await task;
}
///
/// Allows you to cancel awaiting for a non-cancellable task.
///
///
/// Read http://blogs.msdn.com/b/pfxteam/archive/2012/10/05/how-do-i-cancel-non-cancelable-async-operations.aspx
/// and be very careful with this.
///
internal static async Task WithCancellation(this Task task, CancellationToken cancellationToken)
{
var tcs = new TaskCompletionSource();
using (cancellationToken.Register(
s => ((TaskCompletionSource)s).TrySetResult(true), tcs))
if (task != await Task.WhenAny(task, tcs.Task))
throw new TaskCanceledException(task);
await task;
}
internal static Task WithCancellationAndTimeout(this Task task, NpgsqlTimeout timeout, CancellationToken cancellationToken)
{
return task
.WithCancellation(cancellationToken)
.WithTimeout(timeout);
}
internal static Task WithCancellationAndTimeout(this Task task, NpgsqlTimeout timeout, CancellationToken cancellationToken)
{
return task
.WithCancellation(cancellationToken)
.WithTimeout(timeout);
}
}
}