<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="9.0.0" />

ManualResetValueTaskSourceCore<TResult>

public struct ManualResetValueTaskSourceCore<TResult>
Provides the core logic for implementing a manual-reset IValueTaskSource or IValueTaskSource<T>.
using System.Runtime.CompilerServices; using System.Runtime.ExceptionServices; using System.Runtime.InteropServices; namespace System.Threading.Tasks.Sources { [StructLayout(LayoutKind.Auto)] [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] public struct ManualResetValueTaskSourceCore<[System.Runtime.CompilerServices.Nullable(2)] TResult> { private Action<object> _continuation; private object _continuationState; private ExecutionContext _executionContext; private object _capturedContext; private bool _completed; private TResult _result; private ExceptionDispatchInfo _error; private short _version; public bool RunContinuationsAsynchronously { [System.Runtime.CompilerServices.IsReadOnly] get; set; } public short Version => _version; public void Reset() { _version++; _completed = false; _result = default(TResult); _error = null; _executionContext = null; _capturedContext = null; _continuation = null; _continuationState = null; } public void SetResult(TResult result) { _result = result; SignalCompletion(); } public void SetException(Exception error) { _error = ExceptionDispatchInfo.Capture(error); SignalCompletion(); } public ValueTaskSourceStatus GetStatus(short token) { ValidateToken(token); if (_continuation != null && _completed) { if (_error != null) { if (!(_error.SourceException is OperationCanceledException)) return ValueTaskSourceStatus.Faulted; return ValueTaskSourceStatus.Canceled; } return ValueTaskSourceStatus.Succeeded; } return ValueTaskSourceStatus.Pending; } public TResult GetResult(short token) { ValidateToken(token); if (!_completed) throw new InvalidOperationException(); _error?.Throw(); return _result; } [System.Runtime.CompilerServices.NullableContext(2)] public void OnCompleted([System.Runtime.CompilerServices.Nullable(new byte[] { 1, 2 })] Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) { if (continuation == null) throw new ArgumentNullException("continuation"); ValidateToken(token); if ((flags & ValueTaskSourceOnCompletedFlags.FlowExecutionContext) != 0) _executionContext = ExecutionContext.Capture(); if ((flags & ValueTaskSourceOnCompletedFlags.UseSchedulingContext) != 0) { SynchronizationContext current = SynchronizationContext.Current; if (current != null && current.GetType() != typeof(SynchronizationContext)) _capturedContext = current; else { TaskScheduler current2 = TaskScheduler.Current; if (current2 != TaskScheduler.Default) _capturedContext = current2; } } object obj = _continuation; if (obj == null) { _continuationState = state; obj = Interlocked.CompareExchange<Action<object>>(ref _continuation, continuation, (Action<object>)null); } if (obj != null) { if (obj != System.Threading.Tasks.Sources.ManualResetValueTaskSourceCoreShared.s_sentinel) throw new InvalidOperationException(); object capturedContext = _capturedContext; if (capturedContext != null) { SynchronizationContext synchronizationContext = capturedContext as SynchronizationContext; if (synchronizationContext == null) { TaskScheduler taskScheduler = capturedContext as TaskScheduler; if (taskScheduler != null) Task.Factory.StartNew(continuation, state, CancellationToken.None, TaskCreationOptions.DenyChildAttach, taskScheduler); } else synchronizationContext.Post(delegate(object s) { Tuple<Action<object>, object> tuple = (Tuple<Action<object>, object>)s; tuple.Item1(tuple.Item2); }, Tuple.Create<Action<object>, object>(continuation, state)); } else Task.Factory.StartNew(continuation, state, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); } } private void ValidateToken(short token) { if (token != _version) throw new InvalidOperationException(); } private void SignalCompletion() { if (_completed) throw new InvalidOperationException(); _completed = true; if (_continuation != null || Interlocked.CompareExchange<Action<object>>(ref _continuation, System.Threading.Tasks.Sources.ManualResetValueTaskSourceCoreShared.s_sentinel, (Action<object>)null) != null) { if (_executionContext != null) ExecutionContext.Run(_executionContext, delegate(object s) { ((ManualResetValueTaskSourceCore<TResult>)s).InvokeContinuation(); }, this); else InvokeContinuation(); } } private void InvokeContinuation() { object capturedContext = _capturedContext; if (capturedContext != null) { SynchronizationContext synchronizationContext = capturedContext as SynchronizationContext; if (synchronizationContext == null) { TaskScheduler taskScheduler = capturedContext as TaskScheduler; if (taskScheduler != null) Task.Factory.StartNew(_continuation, _continuationState, CancellationToken.None, TaskCreationOptions.DenyChildAttach, taskScheduler); } else synchronizationContext.Post(delegate(object s) { Tuple<Action<object>, object> tuple = (Tuple<Action<object>, object>)s; tuple.Item1(tuple.Item2); }, Tuple.Create<Action<object>, object>(_continuation, _continuationState)); } else if (RunContinuationsAsynchronously) { Task.Factory.StartNew(_continuation, _continuationState, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); } else { _continuation(_continuationState); } } } }