1
0

Utilities.cs 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the Apache 2.0 License.
  3. // See the LICENSE file in the project root for more information.
  4. using System.Collections.Generic;
  5. using System.Threading;
  6. using System.Threading.Tasks;
  7. namespace System.Linq
  8. {
  9. internal static class Utilities
  10. {
  11. public static async ValueTask AddRangeAsync<T>(this List<T> list, IAsyncEnumerable<T> collection, CancellationToken cancellationToken)
  12. {
  13. if (collection is IEnumerable<T> enumerable)
  14. {
  15. list.AddRange(enumerable);
  16. return;
  17. }
  18. if (collection is IAsyncIListProvider<T> listProvider)
  19. {
  20. var count = await listProvider.GetCountAsync(onlyIfCheap: true, cancellationToken).ConfigureAwait(false);
  21. if (count == 0)
  22. {
  23. return;
  24. }
  25. if (count > 0)
  26. {
  27. var newCount = list.Count + count;
  28. if (list.Capacity < newCount)
  29. {
  30. list.Capacity = newCount;
  31. }
  32. }
  33. }
  34. #if USE_AWAIT_FOREACH
  35. await foreach (var item in collection.WithCancellation(cancellationToken).ConfigureAwait(false))
  36. {
  37. list.Add(item);
  38. }
  39. #else
  40. var e = collection.GetAsyncEnumerator(cancellationToken);
  41. try
  42. {
  43. while (await e.MoveNextAsync().ConfigureAwait(false))
  44. {
  45. list.Add(e.Current);
  46. }
  47. }
  48. finally
  49. {
  50. await e.DisposeAsync().ConfigureAwait(false);
  51. }
  52. #endif
  53. }
  54. }
  55. }