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);
}
}
}