Using.cs 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  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. {
  23. await foreach (var item in enumerableFactory(resource).WithCancellation(cancellationToken).ConfigureAwait(false))
  24. {
  25. yield return item;
  26. }
  27. }
  28. }
  29. }
  30. public static IAsyncEnumerable<TSource> Using<TSource, TResource>(Func<Task<TResource>> resourceFactory, Func<TResource, ValueTask<IAsyncEnumerable<TSource>>> enumerableFactory) where TResource : IDisposable
  31. {
  32. if (resourceFactory == null)
  33. throw Error.ArgumentNull(nameof(resourceFactory));
  34. if (enumerableFactory == null)
  35. throw Error.ArgumentNull(nameof(enumerableFactory));
  36. return AsyncEnumerable.Create(Core);
  37. async IAsyncEnumerator<TSource> Core(CancellationToken cancellationToken)
  38. {
  39. using (var resource = await resourceFactory().ConfigureAwait(false))
  40. {
  41. await foreach (var item in (await enumerableFactory(resource).ConfigureAwait(false)).WithCancellation(cancellationToken).ConfigureAwait(false))
  42. {
  43. yield return item;
  44. }
  45. }
  46. }
  47. }
  48. #if !NO_DEEP_CANCELLATION
  49. public static IAsyncEnumerable<TSource> Using<TSource, TResource>(Func<CancellationToken, Task<TResource>> resourceFactory, Func<TResource, CancellationToken, ValueTask<IAsyncEnumerable<TSource>>> enumerableFactory) where TResource : IDisposable
  50. {
  51. if (resourceFactory == null)
  52. throw Error.ArgumentNull(nameof(resourceFactory));
  53. if (enumerableFactory == null)
  54. throw Error.ArgumentNull(nameof(enumerableFactory));
  55. return AsyncEnumerable.Create(Core);
  56. async IAsyncEnumerator<TSource> Core(CancellationToken cancellationToken)
  57. {
  58. using (var resource = await resourceFactory(cancellationToken).ConfigureAwait(false))
  59. {
  60. await foreach (var item in (await enumerableFactory(resource, cancellationToken).ConfigureAwait(false)).WithCancellation(cancellationToken).ConfigureAwait(false))
  61. {
  62. yield return item;
  63. }
  64. }
  65. }
  66. }
  67. #endif
  68. }
  69. }