Esempio n. 1
0
        public void OnCompleted(Action <object> continuation, object state, ValueTaskSourceOnCompletedFlags flags, out CompletionData completionData, out bool doubleCompletion)
        {
            completionData = default;

            doubleCompletion = false;
            Action <object> awaitableState = _completion;

            if (ReferenceEquals(awaitableState, s_awaitableIsNotCompleted))
            {
                _completion      = continuation;
                _completionState = state;

                // Capture the SynchronizationContext if there's any and we're allowing capture (from pipe options)
                if (_useSynchronizationContext && (flags & ValueTaskSourceOnCompletedFlags.UseSchedulingContext) != 0)
                {
                    SynchronizationContext sc = SynchronizationContext.Current;
                    if (sc != null && sc.GetType() != typeof(SynchronizationContext))
                    {
                        _synchronizationContext = SynchronizationContext.Current;
                    }
                }

                // Capture the execution context
                if ((flags & ValueTaskSourceOnCompletedFlags.FlowExecutionContext) != 0)
                {
                    _executionContext = ExecutionContext.Capture();
                }
            }

            if (ReferenceEquals(awaitableState, s_awaitableIsCompleted))
            {
                completionData = new CompletionData(continuation, state, _executionContext, _synchronizationContext);
                return;
            }

            if (!ReferenceEquals(awaitableState, s_awaitableIsNotCompleted))
            {
                doubleCompletion = true;
                completionData   = new CompletionData(continuation, state, _executionContext, _synchronizationContext);
            }
        }
Esempio n. 2
0
        public void Complete(out CompletionData completionData)
        {
            ExtractCompletion(out completionData);

            _awaitableState |= AwaitableState.Completed;
        }
Esempio n. 3
0
        public void OnCompleted(Action <object?> continuation, object?state, ValueTaskSourceOnCompletedFlags flags, out CompletionData completionData, out bool doubleCompletion)
        {
            completionData   = default;
            doubleCompletion = _completion is not null;

            if (IsCompleted || doubleCompletion)
            {
                completionData = new CompletionData(continuation, state, _schedulingContext?.ExecutionContext, _schedulingContext?.SynchronizationContext);
                return;
            }

            _completion      = continuation;
            _completionState = state;

            // Capture the SynchronizationContext if there's any and we're allowing capture (from pipe options)
            if ((_awaitableState & AwaitableState.UseSynchronizationContext) != 0 &&
                (flags & ValueTaskSourceOnCompletedFlags.UseSchedulingContext) != 0)
            {
                SynchronizationContext?sc = SynchronizationContext.Current;
                if (sc != null && sc.GetType() != typeof(SynchronizationContext))
                {
                    _schedulingContext ??= new SchedulingContext();
                    _schedulingContext.SynchronizationContext = sc;
                }
            }

            // Capture the execution context
            if ((flags & ValueTaskSourceOnCompletedFlags.FlowExecutionContext) != 0)
            {
                _schedulingContext ??= new SchedulingContext();
                _schedulingContext.ExecutionContext = ExecutionContext.Capture();
            }
        }