System.Threading.Tasks.Extensions by Microsoft

<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.6.0" />

 ValueTaskAwaiter

Provides an awaiter for a ValueTask.
using System.Diagnostics; using System.Threading.Tasks; using System.Threading.Tasks.Sources; namespace System.Runtime.CompilerServices { public readonly struct ValueTaskAwaiter : ICriticalNotifyCompletion, INotifyCompletion { internal static readonly Action<object> s_invokeActionDelegate = delegate(object state) { Action action = state as Action; if (action == null) System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.state); else action(); }; private readonly ValueTask _value; public bool IsCompleted { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _value.IsCompleted; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal ValueTaskAwaiter(ValueTask value) { _value = value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Diagnostics.StackTraceHidden] public void GetResult() { _value.ThrowIfCompletedUnsuccessfully(); } public void OnCompleted(Action continuation) { object obj = _value._obj; Task task = obj as Task; TaskAwaiter awaiter; if (task != null) { awaiter = task.GetAwaiter(); awaiter.OnCompleted(continuation); } else if (obj != null) { Unsafe.As<IValueTaskSource>(obj).OnCompleted(s_invokeActionDelegate, continuation, _value._token, ValueTaskSourceOnCompletedFlags.UseSchedulingContext | ValueTaskSourceOnCompletedFlags.FlowExecutionContext); } else { awaiter = ValueTask.CompletedTask.GetAwaiter(); awaiter.OnCompleted(continuation); } } public void UnsafeOnCompleted(Action continuation) { object obj = _value._obj; Task task = obj as Task; TaskAwaiter awaiter; if (task != null) { awaiter = task.GetAwaiter(); awaiter.UnsafeOnCompleted(continuation); } else if (obj != null) { Unsafe.As<IValueTaskSource>(obj).OnCompleted(s_invokeActionDelegate, continuation, _value._token, ValueTaskSourceOnCompletedFlags.UseSchedulingContext); } else { awaiter = ValueTask.CompletedTask.GetAwaiter(); awaiter.UnsafeOnCompleted(continuation); } } } }