HedgingExecutionContext<T>
The context associated with an execution of hedging resilience strategy.
            It holds the resources for all executed hedged tasks (primary + secondary) and is responsible for resource disposal.
            
                using Polly.Hedging.Controller;
using Polly.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace Polly.Hedging.Utils
{
    [System.Runtime.CompilerServices.NullableContext(1)]
    [System.Runtime.CompilerServices.Nullable(0)]
    internal sealed class HedgingExecutionContext<[System.Runtime.CompilerServices.Nullable(2)] T> : IAsyncDisposable
    {
        [System.Runtime.CompilerServices.NullableContext(0)]
        public readonly struct ExecutionInfo<[System.Runtime.CompilerServices.Nullable(2)] TResult> : IEquatable<ExecutionInfo<TResult>>
        {
            [System.Runtime.CompilerServices.Nullable(new byte[] {
                2,
                1
            })]
            [field: System.Runtime.CompilerServices.Nullable(new byte[] {
                2,
                1
            })]
            public TaskExecution<T> Execution {
                [return: System.Runtime.CompilerServices.Nullable(new byte[] {
                    2,
                    1
                })]
                get;
                [param: System.Runtime.CompilerServices.Nullable(new byte[] {
                    2,
                    1
                })]
                set;
            }
            public bool Loaded { get; set; }
            [System.Runtime.CompilerServices.Nullable(new byte[] {
                0,
                1
            })]
            [field: System.Runtime.CompilerServices.Nullable(new byte[] {
                0,
                1
            })]
            public Outcome<TResult>? Outcome {
                [return: System.Runtime.CompilerServices.Nullable(new byte[] {
                    0,
                    1
                })]
                get;
                [param: System.Runtime.CompilerServices.Nullable(new byte[] {
                    0,
                    1
                })]
                set;
            }
            public ExecutionInfo([System.Runtime.CompilerServices.Nullable(new byte[] {
                2,
                1
            })] TaskExecution<T> Execution, bool Loaded, [System.Runtime.CompilerServices.Nullable(new byte[] {
                0,
                1
            })] Outcome<TResult>? Outcome)
            {
                Execution = Execution;
                Loaded = Loaded;
                Outcome = Outcome;
            }
            [CompilerGenerated]
            public override string ToString()
            {
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.Append("ExecutionInfo");
                stringBuilder.Append(" { ");
                if (PrintMembers(stringBuilder))
                    stringBuilder.Append(' ');
                stringBuilder.Append('}');
                return stringBuilder.ToString();
            }
            [CompilerGenerated]
            private bool PrintMembers(StringBuilder builder)
            {
                builder.Append("Execution = ");
                builder.Append(Execution);
                builder.Append(", Loaded = ");
                builder.Append(Loaded.ToString());
                builder.Append(", Outcome = ");
                builder.Append(Outcome.ToString());
                return true;
            }
            public static bool operator !=(ExecutionInfo<TResult> left, ExecutionInfo<TResult> right)
            {
                return !(left == right);
            }
            public static bool operator ==(ExecutionInfo<TResult> left, ExecutionInfo<TResult> right)
            {
                return left.Equals(right);
            }
            [CompilerGenerated]
            public override int GetHashCode()
            {
                return (EqualityComparer<TaskExecution<T>>.Default.GetHashCode(Execution) * -1521134295 + EqualityComparer<bool>.Default.GetHashCode(Loaded)) * -1521134295 + EqualityComparer<Outcome<TResult>?>.Default.GetHashCode(Outcome);
            }
            [CompilerGenerated]
            public override bool Equals(object obj)
            {
                if (obj is ExecutionInfo<TResult>)
                    return Equals((ExecutionInfo<TResult>)obj);
                return false;
            }
            [CompilerGenerated]
            public bool Equals(ExecutionInfo<TResult> other)
            {
                if (EqualityComparer<TaskExecution<T>>.Default.Equals(Execution, other.Execution) && EqualityComparer<bool>.Default.Equals(Loaded, other.Loaded))
                    return EqualityComparer<Outcome<TResult>?>.Default.Equals(Outcome, other.Outcome);
                return false;
            }
            [CompilerGenerated]
            public void Deconstruct([System.Runtime.CompilerServices.Nullable(new byte[] {
                2,
                1
            })] out TaskExecution<T> Execution, out bool Loaded, [System.Runtime.CompilerServices.Nullable(new byte[] {
                0,
                1
            })] out Outcome<TResult>? Outcome)
            {
                Execution = this.Execution;
                Loaded = this.Loaded;
                Outcome = this.Outcome;
            }
        }
        private readonly List<TaskExecution<T>> _tasks = new List<TaskExecution<T>>();
        private readonly List<TaskExecution<T>> _executingTasks = new List<TaskExecution<T>>();
        private readonly ObjectPool<TaskExecution<T>> _executionPool;
        private readonly TimeProvider _timeProvider;
        private readonly int _maxAttempts;
        private readonly Action<HedgingExecutionContext<T>> _onReset;
        public int LoadedTasks => _tasks.Count;
        [System.Runtime.CompilerServices.Nullable(2)]
        [field: System.Runtime.CompilerServices.Nullable(2)]
        public ResilienceContext PrimaryContext {
            [System.Runtime.CompilerServices.NullableContext(2)]
            get;
            [System.Runtime.CompilerServices.NullableContext(2)]
            private set;
        }
        public bool IsInitialized => PrimaryContext != null;
        public IReadOnlyList<TaskExecution<T>> Tasks => _tasks;
        private bool ContinueOnCapturedContext => PrimaryContext.ContinueOnCapturedContext;
        public HedgingExecutionContext(ObjectPool<TaskExecution<T>> executionPool, TimeProvider timeProvider, int maxAttempts, Action<HedgingExecutionContext<T>> onReset)
        {
            _executionPool = executionPool;
            _timeProvider = timeProvider;
            _maxAttempts = maxAttempts;
            _onReset = onReset;
        }
        internal void Initialize(ResilienceContext context)
        {
            PrimaryContext = context;
        }
        [AsyncStateMachine(typeof(<LoadExecutionAsync>d__21<>))]
        [return: System.Runtime.CompilerServices.Nullable(new byte[] {
            0,
            0,
            0,
            1
        })]
        public ValueTask<ExecutionInfo<T>> LoadExecutionAsync<[System.Runtime.CompilerServices.Nullable(2)] TState>([System.Runtime.CompilerServices.Nullable(new byte[] {
            1,
            1,
            1,
            0,
            0,
            1
        })] Func<ResilienceContext, TState, ValueTask<Outcome<T>>> primaryCallback, TState state)
        {
            <LoadExecutionAsync>d__21<TState> stateMachine = default(<LoadExecutionAsync>d__21<TState>);
            stateMachine.<>t__builder = AsyncValueTaskMethodBuilder<ExecutionInfo<T>>.Create();
            stateMachine.<>4__this = this;
            stateMachine.primaryCallback = primaryCallback;
            stateMachine.state = state;
            stateMachine.<>1__state = -1;
            stateMachine.<>t__builder.Start(ref stateMachine);
            return stateMachine.<>t__builder.Task;
        }
        [AsyncStateMachine(typeof(HedgingExecutionContext<>.<DisposeAsync>d__22))]
        public ValueTask DisposeAsync()
        {
            <DisposeAsync>d__22 stateMachine = default(<DisposeAsync>d__22);
            stateMachine.<>t__builder = AsyncValueTaskMethodBuilder.Create();
            stateMachine.<>4__this = this;
            stateMachine.<>1__state = -1;
            stateMachine.<>t__builder.Start<<DisposeAsync>d__22>(ref stateMachine);
            return stateMachine.<>t__builder.Task;
        }
        [AsyncStateMachine(typeof(HedgingExecutionContext<>.<TryWaitForCompletedExecutionAsync>d__23))]
        [return: System.Runtime.CompilerServices.Nullable(new byte[] {
            0,
            2,
            1
        })]
        public ValueTask<TaskExecution<T>> TryWaitForCompletedExecutionAsync(TimeSpan hedgingDelay)
        {
            <TryWaitForCompletedExecutionAsync>d__23 stateMachine = default(<TryWaitForCompletedExecutionAsync>d__23);
            stateMachine.<>t__builder = AsyncValueTaskMethodBuilder<TaskExecution<T>>.Create();
            stateMachine.<>4__this = this;
            stateMachine.hedgingDelay = hedgingDelay;
            stateMachine.<>1__state = -1;
            stateMachine.<>t__builder.Start(ref stateMachine);
            return stateMachine.<>t__builder.Task;
        }
        [return: System.Runtime.CompilerServices.Nullable(new byte[] {
            0,
            0,
            1
        })]
        private ExecutionInfo<T> CreateExecutionInfoWhenNoExecution()
        {
            if (_executingTasks.Count == 0) {
                TaskExecution<T> taskExecution = Enumerable.First<TaskExecution<T>>((IEnumerable<TaskExecution<T>>)_tasks, (Func<TaskExecution<T>, bool>)((TaskExecution<T> t) => t.ExecutionTaskSafe.IsCompleted));
                taskExecution.AcceptOutcome();
                return new ExecutionInfo<T>(null, false, taskExecution.Outcome);
            }
            return new ExecutionInfo<T>(null, false, null);
        }
        private Task<Task> WaitForTaskCompetitionAsync()
        {
            switch (_executingTasks.Count) {
            case 1:
                return <WaitForTaskCompetitionAsync>g__AwaitTask|25_0(_executingTasks[0], ContinueOnCapturedContext);
            case 2:
                return Task.WhenAny(_executingTasks[0].ExecutionTaskSafe, _executingTasks[1].ExecutionTaskSafe);
            default:
                return Task.WhenAny(Enumerable.Select<TaskExecution<T>, Task>((IEnumerable<TaskExecution<T>>)_executingTasks, (Func<TaskExecution<T>, Task>)((TaskExecution<T> v) => v.ExecutionTaskSafe)));
            }
        }
        [return: System.Runtime.CompilerServices.Nullable(new byte[] {
            2,
            1
        })]
        private TaskExecution<T> TryRemoveExecutedTask()
        {
            TaskExecution<T> taskExecution = _executingTasks.Find((TaskExecution<T> v) => v.ExecutionTaskSafe.IsCompleted);
            if (taskExecution != null) {
                _executingTasks.Remove(taskExecution);
                return taskExecution;
            }
            return null;
        }
        private void UpdateOriginalContext()
        {
            if (LoadedTasks != 0) {
                TaskExecution<T> taskExecution = Enumerable.FirstOrDefault<TaskExecution<T>>((IEnumerable<TaskExecution<T>>)Tasks, (Func<TaskExecution<T>, bool>)((TaskExecution<T> t) => t.IsAccepted));
                if (taskExecution != null)
                    PrimaryContext.Properties.AddOrReplaceProperties(taskExecution.Context.Properties);
            }
        }
        private void Reset()
        {
            _tasks.Clear();
            _executingTasks.Clear();
            PrimaryContext = null;
            _onReset(this);
        }
    }
}