System.Threading.Tasks.Extensions by Microsoft

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

 ValueTask

public struct ValueTask : IEquatable<ValueTask>
using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading.Tasks.Sources; namespace System.Threading.Tasks { [StructLayout(LayoutKind.Auto)] [AsyncMethodBuilder(typeof(AsyncValueTaskMethodBuilder))] public readonly struct ValueTask : IEquatable<ValueTask> { private sealed class ValueTaskSourceAsTask : TaskCompletionSource<bool> { private static readonly Action<object> s_completionAction = delegate(object state) { ValueTaskSourceAsTask valueTaskSourceAsTask; IValueTaskSource source; if ((valueTaskSourceAsTask = (state as ValueTaskSourceAsTask)) == null || (source = valueTaskSourceAsTask._source) == null) System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.state); else { valueTaskSourceAsTask._source = null; ValueTaskSourceStatus status = source.GetStatus(valueTaskSourceAsTask._token); try { source.GetResult(valueTaskSourceAsTask._token); valueTaskSourceAsTask.TrySetResult(false); } catch (Exception exception) { if (status == ValueTaskSourceStatus.Canceled) valueTaskSourceAsTask.TrySetCanceled(); else valueTaskSourceAsTask.TrySetException(exception); } } }; private IValueTaskSource _source; private readonly short _token; public ValueTaskSourceAsTask(IValueTaskSource source, short token) { _token = token; _source = source; source.OnCompleted(s_completionAction, this, token, ValueTaskSourceOnCompletedFlags.None); } } private static readonly Task s_canceledTask = Task.Delay(-1, new CancellationToken(true)); internal readonly object _obj; internal readonly short _token; internal readonly bool _continueOnCapturedContext; internal static Task CompletedTask { get; } = Task.Delay(0); public bool IsCompleted { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { object obj = _obj; if (obj == null) return true; Task task; if ((task = (obj as Task)) != null) return task.IsCompleted; return Unsafe.As<IValueTaskSource>(obj).GetStatus(_token) != ValueTaskSourceStatus.Pending; } } public bool IsCompletedSuccessfully { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { object obj = _obj; if (obj == null) return true; Task task; if ((task = (obj as Task)) != null) return task.Status == TaskStatus.RanToCompletion; return Unsafe.As<IValueTaskSource>(obj).GetStatus(_token) == ValueTaskSourceStatus.Succeeded; } } public bool IsFaulted { get { object obj = _obj; if (obj == null) return false; Task task; if ((task = (obj as Task)) != null) return task.IsFaulted; return Unsafe.As<IValueTaskSource>(obj).GetStatus(_token) == ValueTaskSourceStatus.Faulted; } } public bool IsCanceled { get { object obj = _obj; if (obj == null) return false; Task task; if ((task = (obj as Task)) != null) return task.IsCanceled; return Unsafe.As<IValueTaskSource>(obj).GetStatus(_token) == ValueTaskSourceStatus.Canceled; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ValueTask(Task task) { if (task == null) System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.task); _obj = task; _continueOnCapturedContext = true; _token = 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ValueTask(IValueTaskSource source, short token) { if (source == null) System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.source); _obj = source; _token = token; _continueOnCapturedContext = true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private ValueTask(object obj, short token, bool continueOnCapturedContext) { _obj = obj; _token = token; _continueOnCapturedContext = continueOnCapturedContext; } public override int GetHashCode() { return _obj?.GetHashCode() ?? 0; } public override bool Equals(object obj) { if (obj is ValueTask) return Equals((ValueTask)obj); return false; } public bool Equals(ValueTask other) { if (_obj == other._obj) return _token == other._token; return false; } public static bool operator ==(ValueTask left, ValueTask right) { return left.Equals(right); } public static bool operator !=(ValueTask left, ValueTask right) { return !left.Equals(right); } public Task AsTask() { object obj = _obj; object obj2; if (obj != null) { obj2 = (obj as Task); if (obj2 == null) return GetTaskForValueTaskSource(Unsafe.As<IValueTaskSource>(obj)); } else obj2 = CompletedTask; return (Task)obj2; } public ValueTask Preserve() { if (_obj != null) return new ValueTask(AsTask()); return this; } private Task GetTaskForValueTaskSource(IValueTaskSource t) { ValueTaskSourceStatus status = t.GetStatus(_token); if (status != 0) try { t.GetResult(_token); return CompletedTask; } catch (Exception exception) { if (status != ValueTaskSourceStatus.Canceled) { TaskCompletionSource<bool> taskCompletionSource = new TaskCompletionSource<bool>(); taskCompletionSource.TrySetException(exception); return taskCompletionSource.Task; } return s_canceledTask; } ValueTaskSourceAsTask valueTaskSourceAsTask = new ValueTaskSourceAsTask(t, _token); return valueTaskSourceAsTask.Task; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Diagnostics.StackTraceHidden] internal void ThrowIfCompletedUnsuccessfully() { object obj = _obj; if (obj != null) { Task task; if ((task = (obj as Task)) != null) task.GetAwaiter().GetResult(); else Unsafe.As<IValueTaskSource>(obj).GetResult(_token); } } public ValueTaskAwaiter GetAwaiter() { return new ValueTaskAwaiter(this); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ConfiguredValueTaskAwaitable ConfigureAwait(bool continueOnCapturedContext) { return new ConfiguredValueTaskAwaitable(new ValueTask(_obj, _token, continueOnCapturedContext)); } } }