/* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ using Amazon.S3.Model; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace Amazon.S3.Transfer.Internal { internal abstract partial class BaseCommand { public abstract Task ExecuteAsync(CancellationToken cancellationToken); /// /// Waits for all of the tasks to complete or till any task fails or is canceled. /// protected static async Task> WhenAllOrFirstExceptionAsync(List> pendingTasks, CancellationToken cancellationToken) { int processed = 0; int total = pendingTasks.Count; var responses = new List(); while (processed < total) { cancellationToken.ThrowIfCancellationRequested(); var completedTask = await Task.WhenAny(pendingTasks) .ConfigureAwait(continueOnCapturedContext: false); //If RanToCompletion a response will be returned //If Faulted or Canceled an appropriate exception will be thrown var response = await completedTask .ConfigureAwait(continueOnCapturedContext: false); responses.Add(response); pendingTasks.Remove(completedTask); processed++; } return responses; } /// /// Waits for all of the tasks to complete or till any task fails or is canceled. /// protected static async Task WhenAllOrFirstExceptionAsync(List pendingTasks, CancellationToken cancellationToken) { int processed = 0; int total = pendingTasks.Count; while (processed < total) { cancellationToken.ThrowIfCancellationRequested(); var completedTask = await Task.WhenAny(pendingTasks) .ConfigureAwait(continueOnCapturedContext: false); //If RanToCompletion a response will be returned //If Faulted or Canceled an appropriate exception will be thrown await completedTask .ConfigureAwait(continueOnCapturedContext: false); pendingTasks.Remove(completedTask); processed++; } } protected static async Task ExecuteCommandAsync(BaseCommand command, CancellationTokenSource internalCts, SemaphoreSlim throttler) { try { await command.ExecuteAsync(internalCts.Token) .ConfigureAwait(continueOnCapturedContext: false); } catch (Exception exception) { if (!(exception is OperationCanceledException)) { // Cancel scheduling any more tasks. // Cancel other upload requests. internalCts.Cancel(); } throw; } finally { throttler.Release(); } } } }