<PackageReference Include="System.IO.Pipelines" Version="10.0.0-preview.2.25163.2" />

PipeAwaitable

struct PipeAwaitable
using System.Diagnostics; using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks.Sources; namespace System.IO.Pipelines { [NullableContext(2)] [Nullable(0)] [DebuggerDisplay("CanceledState = {_awaitableState}, IsCompleted = {IsCompleted}")] internal struct PipeAwaitable { [Flags] private enum AwaitableState { None = 0, Completed = 1, Running = 2, Canceled = 4, UseSynchronizationContext = 8 } private sealed class SchedulingContext { public SynchronizationContext SynchronizationContext { get; set; } public ExecutionContext ExecutionContext { get; set; } } private AwaitableState _awaitableState; private Action<object> _completion; private object _completionState; private SchedulingContext _schedulingContext; private CancellationTokenRegistration _cancellationTokenRegistration; private CancellationToken CancellationToken => _cancellationTokenRegistration.Token; public bool IsCompleted => (_awaitableState & (AwaitableState.Completed | AwaitableState.Canceled)) != AwaitableState.None; public bool IsRunning => (_awaitableState & AwaitableState.Running) != AwaitableState.None; public PipeAwaitable(bool completed, bool useSynchronizationContext) { _awaitableState = (AwaitableState)((completed ? 1 : 0) | (useSynchronizationContext ? 8 : 0)); _completion = null; _completionState = null; _cancellationTokenRegistration = default(CancellationTokenRegistration); _schedulingContext = null; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void BeginOperation(CancellationToken cancellationToken, [Nullable(new byte[] { 1, 2 })] Action<object> callback, object state) { if (cancellationToken.CanBeCanceled && !IsCompleted) { _cancellationTokenRegistration = cancellationToken.UnsafeRegister(callback, state); if (_cancellationTokenRegistration == default(CancellationTokenRegistration)) cancellationToken.ThrowIfCancellationRequested(); } _awaitableState |= AwaitableState.Running; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Complete(out CompletionData completionData) { ExtractCompletion(out completionData); _awaitableState |= AwaitableState.Completed; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void ExtractCompletion(out CompletionData completionData) { Action<object> completion = _completion; object completionState = _completionState; SchedulingContext schedulingContext = _schedulingContext; ExecutionContext executionContext = schedulingContext?.ExecutionContext; SynchronizationContext synchronizationContext = schedulingContext?.SynchronizationContext; _completion = null; _completionState = null; _schedulingContext = null; completionData = ((completion != null) ? new CompletionData(completion, completionState, executionContext, synchronizationContext) : default(CompletionData)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void SetUncompleted() { _awaitableState &= ~AwaitableState.Completed; } public void OnCompleted([Nullable(new byte[] { 1, 2 })] Action<object> continuation, object state, ValueTaskSourceOnCompletedFlags flags, out CompletionData completionData, out bool doubleCompletion) { completionData = default(CompletionData); doubleCompletion = (_completion != null); if (IsCompleted | doubleCompletion) completionData = new CompletionData(continuation, state, _schedulingContext?.ExecutionContext, _schedulingContext?.SynchronizationContext); else { _completion = continuation; _completionState = state; if ((_awaitableState & AwaitableState.UseSynchronizationContext) != 0 && (flags & ValueTaskSourceOnCompletedFlags.UseSchedulingContext) != 0) { SynchronizationContext current = SynchronizationContext.Current; if (current != null && current.GetType() != typeof(SynchronizationContext)) { if (_schedulingContext == null) _schedulingContext = new SchedulingContext(); _schedulingContext.SynchronizationContext = current; } } if ((flags & ValueTaskSourceOnCompletedFlags.FlowExecutionContext) != 0) { if (_schedulingContext == null) _schedulingContext = new SchedulingContext(); _schedulingContext.ExecutionContext = ExecutionContext.Capture(); } } } public void Cancel(out CompletionData completionData) { ExtractCompletion(out completionData); _awaitableState |= AwaitableState.Canceled; } public void CancellationTokenFired(out CompletionData completionData) { if (CancellationToken.IsCancellationRequested) Cancel(out completionData); else completionData = default(CompletionData); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool ObserveCancellation() { bool result = (_awaitableState & AwaitableState.Canceled) == AwaitableState.Canceled; _awaitableState &= ~(AwaitableState.Running | AwaitableState.Canceled); return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public CancellationTokenRegistration ReleaseCancellationTokenRegistration(out CancellationToken cancellationToken) { cancellationToken = CancellationToken; CancellationTokenRegistration cancellationTokenRegistration = _cancellationTokenRegistration; _cancellationTokenRegistration = default(CancellationTokenRegistration); return cancellationTokenRegistration; } } }