PageRenderTime 23ms CodeModel.GetById 35ms RepoModel.GetById 0ms app.codeStats 0ms

/sdk/src/Services/S3/Custom/_bcl+pcl/Transfer/Internal/_async/BaseCommand.async.cs

https://gitlab.com/vectorci/aws-sdk-net
C# | 108 lines | 75 code | 7 blank | 26 comment | 8 complexity | 55886959c3d9adb192596f346c28eb8a MD5 | raw file
  1. /*
  2. * Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License").
  5. * You may not use this file except in compliance with the License.
  6. * A copy of the License is located at
  7. *
  8. * http://aws.amazon.com/apache2.0
  9. *
  10. * or in the "license" file accompanying this file. This file is distributed
  11. * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
  12. * express or implied. See the License for the specific language governing
  13. * permissions and limitations under the License.
  14. */
  15. using Amazon.S3.Model;
  16. using System;
  17. using System.Collections.Generic;
  18. using System.IO;
  19. using System.Linq;
  20. using System.Text;
  21. using System.Threading;
  22. using System.Threading.Tasks;
  23. namespace Amazon.S3.Transfer.Internal
  24. {
  25. internal abstract partial class BaseCommand
  26. {
  27. public abstract Task ExecuteAsync(CancellationToken cancellationToken);
  28. /// <summary>
  29. /// Waits for all of the tasks to complete or till any task fails.
  30. /// </summary>
  31. protected static async Task<List<T>> WhenAllOrFirstExceptionAsync<T>(List<Task<T>> pendingTasks, CancellationToken cancellationToken)
  32. {
  33. int processed = 0;
  34. int total = pendingTasks.Count;
  35. var responses = new List<T>();
  36. while (processed < total)
  37. {
  38. cancellationToken.ThrowIfCancellationRequested();
  39. var completedTask = await Task.WhenAny(pendingTasks)
  40. .ConfigureAwait(continueOnCapturedContext: false);
  41. if (completedTask.Status == TaskStatus.RanToCompletion ||
  42. completedTask.Status == TaskStatus.Faulted)
  43. {
  44. // Only process results from completed or faulted tasks.
  45. // so that we can capture the result of the operation or the exception,
  46. // and ignore OperationCancelledException from cancelled tasks.
  47. var response = await completedTask
  48. .ConfigureAwait(continueOnCapturedContext: false);
  49. responses.Add(response);
  50. }
  51. pendingTasks.Remove(completedTask);
  52. processed++;
  53. }
  54. return responses;
  55. }
  56. /// <summary>
  57. /// Waits for all of the tasks to complete or till any task fails.
  58. /// </summary>
  59. protected static async Task WhenAllOrFirstExceptionAsync(List<Task> pendingTasks, CancellationToken cancellationToken)
  60. {
  61. int processed = 0;
  62. int total = pendingTasks.Count;
  63. while (processed < total)
  64. {
  65. cancellationToken.ThrowIfCancellationRequested();
  66. var completedTask = await Task.WhenAny(pendingTasks)
  67. .ConfigureAwait(continueOnCapturedContext: false);
  68. if (completedTask.Status == TaskStatus.Faulted)
  69. {
  70. // Only process results from faulted tasks so that the exception is thrown.
  71. await completedTask
  72. .ConfigureAwait(continueOnCapturedContext: false);
  73. }
  74. pendingTasks.Remove(completedTask);
  75. processed++;
  76. }
  77. }
  78. protected static async Task ExecuteCommandAsync(BaseCommand command, CancellationTokenSource internalCts, SemaphoreSlim throttler)
  79. {
  80. try
  81. {
  82. await command.ExecuteAsync(internalCts.Token)
  83. .ConfigureAwait(continueOnCapturedContext: false);
  84. }
  85. catch (Exception exception)
  86. {
  87. if (!(exception is OperationCanceledException))
  88. {
  89. // Cancel scheduling any more tasks.
  90. // Cancel other upload requests.
  91. internalCts.Cancel();
  92. }
  93. throw;
  94. }
  95. finally
  96. {
  97. throttler.Release();
  98. }
  99. }
  100. }
  101. }