public static CombinedCancellationToken CombineWith()

in src/Microsoft.VisualStudio.Threading/CancellationTokenExtensions.cs [43:128]


        public static CombinedCancellationToken CombineWith(this CancellationToken original, params CancellationToken[] others)
        {
            Requires.NotNull(others, nameof(others));

            if (original.IsCancellationRequested)
            {
                return new CombinedCancellationToken(original);
            }

            int cancelableTokensCount = original.CanBeCanceled ? 1 : 0;
            foreach (CancellationToken other in others)
            {
                if (other.IsCancellationRequested)
                {
                    return new CombinedCancellationToken(other);
                }

                if (other.CanBeCanceled)
                {
                    cancelableTokensCount++;
                }
            }

            switch (cancelableTokensCount)
            {
                case 0:
                    return new CombinedCancellationToken(CancellationToken.None);
                case 1:
                    if (original.CanBeCanceled)
                    {
                        return new CombinedCancellationToken(original);
                    }

                    foreach (CancellationToken other in others)
                    {
                        if (other.CanBeCanceled)
                        {
                            return new CombinedCancellationToken(other);
                        }
                    }

                    throw Assumes.NotReachable();
                case 2:
                    CancellationToken first = CancellationToken.None;
                    CancellationToken second = CancellationToken.None;

                    if (original.CanBeCanceled)
                    {
                        first = original;
                    }

                    foreach (CancellationToken other in others)
                    {
                        if (other.CanBeCanceled)
                        {
                            if (first.CanBeCanceled)
                            {
                                second = other;
                            }
                            else
                            {
                                first = other;
                            }
                        }
                    }

                    Assumes.True(first.CanBeCanceled && second.CanBeCanceled);

                    // Call the overload that takes two CancellationTokens explicitly to avoid an array allocation.
                    return new CombinedCancellationToken(CancellationTokenSource.CreateLinkedTokenSource(first, second));
                default:
                    // This is the most expensive path to take since it involves allocating memory and requiring disposal.
                    // Before this point we've checked every condition that would allow us to avoid it.
                    var cancelableTokens = new CancellationToken[cancelableTokensCount];
                    int i = 0;
                    foreach (CancellationToken other in others)
                    {
                        if (other.CanBeCanceled)
                        {
                            cancelableTokens[i++] = other;
                        }
                    }

                    return new CombinedCancellationToken(CancellationTokenSource.CreateLinkedTokenSource(cancelableTokens));
            }
        }