DotNext by .NET Foundation and Contributors

<PackageReference Include="DotNext" Version="4.0.0-beta.1" />

 Continuation

public static class Continuation
Represents various continuations.
using DotNext.Generic; using DotNext.Runtime; using System; using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; namespace DotNext.Threading.Tasks { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] public static class Continuation { [System.Runtime.CompilerServices.Nullable(new byte[] { 1, 1, 2 })] private static readonly Action<Task, object> WhenFaultedOrCanceledAction = WhenFaultedOrCanceled; private static void WhenFaultedOrCanceled(Task task, [System.Runtime.CompilerServices.Nullable(2)] object state) { task.ConfigureAwait(false).GetAwaiter().GetResult(); } public static Task<Task> OnCompleted(this Task task) { return task.ContinueWith(Func.Identity<Task>(), Intrinsics.DefaultOf<CancellationToken>(), TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Current); } public static Task<Task<TResult>> OnCompleted<[System.Runtime.CompilerServices.Nullable(2)] TResult>(this Task<TResult> task) { return task.ContinueWith(Func.Identity<Task<TResult>>(), Intrinsics.DefaultOf<CancellationToken>(), TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Current); } public static Task<T> OnFaulted<[System.Runtime.CompilerServices.Nullable(2)] T, [System.Runtime.CompilerServices.Nullable(0)] TConstant>(this Task<T> task, [System.Runtime.CompilerServices.Nullable(2)] TaskScheduler scheduler = null) where TConstant : Constant<T>, new { return task.OnFaulted<T, TConstant>(Predicate.True<AggregateException>(), scheduler); } public static Task<T> OnFaulted<[System.Runtime.CompilerServices.Nullable(2)] T, [System.Runtime.CompilerServices.Nullable(0)] TConstant>(this Task<T> task, Predicate<AggregateException> filter, [System.Runtime.CompilerServices.Nullable(2)] TaskScheduler scheduler = null) where TConstant : Constant<T>, new { TaskStatus status = task.Status; if ((uint)(status - 5) > 1) { if (status != TaskStatus.Faulted) return task.ContinueWith(Continuation<T, TConstant>.WhenFaulted, filter, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, scheduler ?? TaskScheduler.Current); if (filter(task.Exception)) return CompletedTask<T, TConstant>.Task; } return task; } public static Task<T> OnFaultedOrCanceled<[System.Runtime.CompilerServices.Nullable(2)] T, [System.Runtime.CompilerServices.Nullable(0)] TConstant>(this Task<T> task, [System.Runtime.CompilerServices.Nullable(2)] TaskScheduler scheduler = null) where TConstant : Constant<T>, new { return task.OnFaultedOrCanceled<T, TConstant>(Predicate.True<AggregateException>(), scheduler); } public static Task<T> OnFaultedOrCanceled<[System.Runtime.CompilerServices.Nullable(2)] T, [System.Runtime.CompilerServices.Nullable(0)] TConstant>(this Task<T> task, Predicate<AggregateException> filter, [System.Runtime.CompilerServices.Nullable(2)] TaskScheduler scheduler = null) where TConstant : Constant<T>, new { switch (task.Status) { case TaskStatus.Faulted: if (!filter(task.Exception)) break; goto case TaskStatus.Canceled; case TaskStatus.Canceled: task = CompletedTask<T, TConstant>.Task; break; default: task = task.ContinueWith(Continuation<T, TConstant>.WhenFaultedOrCanceled, filter, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, scheduler ?? TaskScheduler.Current); break; case TaskStatus.RanToCompletion: break; } return task; } public static Task<T> OnCanceled<[System.Runtime.CompilerServices.Nullable(2)] T, [System.Runtime.CompilerServices.Nullable(0)] TConstant>(this Task<T> task, [System.Runtime.CompilerServices.Nullable(2)] TaskScheduler scheduler = null) where TConstant : Constant<T>, new { switch (task.Status) { case TaskStatus.Canceled: return CompletedTask<T, TConstant>.Task; case TaskStatus.RanToCompletion: case TaskStatus.Faulted: return task; default: return task.ContinueWith(Continuation<T, TConstant>.WhenCanceled, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, scheduler ?? TaskScheduler.Current); } } internal static void OnCompleted(this Task task, AsyncCallback callback) { if (task.IsCompleted) callback(task); else task.ConfigureAwait(false).GetAwaiter().OnCompleted(delegate { callback(task); }); } internal static Task AttachState(this Task task, [System.Runtime.CompilerServices.Nullable(2)] object state, CancellationToken token = default(CancellationToken)) { return task.ContinueWith(WhenFaultedOrCanceledAction, state, token, TaskContinuationOptions.None, TaskScheduler.Default); } } }