Using.cs 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  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. public static partial class AsyncEnumerableEx
  10. {
  11. // REVIEW: Add support for IAsyncDisposable resources.
  12. public static IAsyncEnumerable<TSource> Using<TSource, TResource>(Func<TResource> resourceFactory, Func<TResource, IAsyncEnumerable<TSource>> enumerableFactory) where TResource : IDisposable
  13. {
  14. if (resourceFactory == null)
  15. throw Error.ArgumentNull(nameof(resourceFactory));
  16. if (enumerableFactory == null)
  17. throw Error.ArgumentNull(nameof(enumerableFactory));
  18. return AsyncEnumerable.Create(Core);
  19. async IAsyncEnumerator<TSource> Core(CancellationToken cancellationToken)
  20. {
  21. using var resource = resourceFactory();
  22. await foreach (var item in enumerableFactory(resource).WithCancellation(cancellationToken).ConfigureAwait(false))
  23. {
  24. yield return item;
  25. }
  26. }
  27. }
  28. public static IAsyncEnumerable<TSource> Using<TSource, TResource>(Func<Task<TResource>> resourceFactory, Func<TResource, ValueTask<IAsyncEnumerable<TSource>>> enumerableFactory) where TResource : IDisposable
  29. {
  30. if (resourceFactory == null)
  31. throw Error.ArgumentNull(nameof(resourceFactory));
  32. if (enumerableFactory == null)
  33. throw Error.ArgumentNull(nameof(enumerableFactory));
  34. return AsyncEnumerable.Create(Core);
  35. async IAsyncEnumerator<TSource> Core(CancellationToken cancellationToken)
  36. {
  37. using var resource = await resourceFactory().ConfigureAwait(false);
  38. await foreach (var item in (await enumerableFactory(resource).ConfigureAwait(false)).WithCancellation(cancellationToken).ConfigureAwait(false))
  39. {
  40. yield return item;
  41. }
  42. }
  43. }
  44. #if !NO_DEEP_CANCELLATION
  45. public static IAsyncEnumerable<TSource> Using<TSource, TResource>(Func<CancellationToken, Task<TResource>> resourceFactory, Func<TResource, CancellationToken, ValueTask<IAsyncEnumerable<TSource>>> enumerableFactory) where TResource : IDisposable
  46. {
  47. if (resourceFactory == null)
  48. throw Error.ArgumentNull(nameof(resourceFactory));
  49. if (enumerableFactory == null)
  50. throw Error.ArgumentNull(nameof(enumerableFactory));
  51. return AsyncEnumerable.Create(Core);
  52. async IAsyncEnumerator<TSource> Core(CancellationToken cancellationToken)
  53. {
  54. using var resource = await resourceFactory(cancellationToken).ConfigureAwait(false);
  55. await foreach (var item in (await enumerableFactory(resource, cancellationToken).ConfigureAwait(false)).WithCancellation(cancellationToken).ConfigureAwait(false))
  56. {
  57. yield return item;
  58. }
  59. }
  60. }
  61. #endif
  62. }
  63. }