|
@@ -1,6 +1,7 @@
|
|
|
// Licensed to the .NET Foundation under one or more agreements.
|
|
|
// The .NET Foundation licenses this file to you under the Apache 2.0 License.
|
|
|
// See the LICENSE file in the project root for more information.
|
|
|
+
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Linq;
|
|
@@ -11,57 +12,43 @@ namespace System.Linq
|
|
|
{
|
|
|
public static partial class AsyncEnumerable
|
|
|
{
|
|
|
- public static IAsyncEnumerable<T> Create<T>(Func<IAsyncEnumerator<T>> getEnumerator)
|
|
|
+ public static IAsyncEnumerable<T> CreateEnumerable<T>(Func<IAsyncEnumerator<T>> getEnumerator)
|
|
|
{
|
|
|
return new AnonymousAsyncEnumerable<T>(getEnumerator);
|
|
|
}
|
|
|
|
|
|
- private class AnonymousAsyncEnumerable<T> : IAsyncEnumerable<T>
|
|
|
+ public static IAsyncEnumerator<T> CreateEnumerator<T>(Func<CancellationToken, Task<bool>> moveNext, Func<T> current, Action dispose)
|
|
|
{
|
|
|
- private Func<IAsyncEnumerator<T>> getEnumerator;
|
|
|
-
|
|
|
- public AnonymousAsyncEnumerable(Func<IAsyncEnumerator<T>> getEnumerator)
|
|
|
- {
|
|
|
- this.getEnumerator = getEnumerator;
|
|
|
- }
|
|
|
-
|
|
|
- public IAsyncEnumerator<T> GetEnumerator()
|
|
|
- {
|
|
|
- return getEnumerator();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private static IAsyncEnumerator<T> Create<T>(Func<CancellationToken, Task<bool>> moveNext, Func<T> current,
|
|
|
- Action dispose, IDisposable enumerator)
|
|
|
- {
|
|
|
- return Create(async ct =>
|
|
|
- {
|
|
|
- using (ct.Register(dispose))
|
|
|
- {
|
|
|
- try
|
|
|
- {
|
|
|
- var result = await moveNext(ct).ConfigureAwait(false);
|
|
|
- if (!result)
|
|
|
- {
|
|
|
- enumerator?.Dispose();
|
|
|
- }
|
|
|
- return result;
|
|
|
- }
|
|
|
- catch
|
|
|
- {
|
|
|
- enumerator?.Dispose();
|
|
|
- throw;
|
|
|
- }
|
|
|
- }
|
|
|
- }, current, dispose);
|
|
|
+ return new AnonymousAsyncEnumerator<T>(moveNext, current, dispose);
|
|
|
}
|
|
|
|
|
|
- public static IAsyncEnumerator<T> Create<T>(Func<CancellationToken, Task<bool>> moveNext, Func<T> current, Action dispose)
|
|
|
+ private static IAsyncEnumerator<T> CreateEnumerator<T>(Func<CancellationToken, Task<bool>> moveNext, Func<T> current,
|
|
|
+ Action dispose, IDisposable enumerator)
|
|
|
{
|
|
|
- return new AnonymousAsyncEnumerator<T>(moveNext, current, dispose);
|
|
|
+ return CreateEnumerator(async ct =>
|
|
|
+ {
|
|
|
+ using (ct.Register(dispose))
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ var result = await moveNext(ct)
|
|
|
+ .ConfigureAwait(false);
|
|
|
+ if (!result)
|
|
|
+ {
|
|
|
+ enumerator?.Dispose();
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ catch
|
|
|
+ {
|
|
|
+ enumerator?.Dispose();
|
|
|
+ throw;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }, current, dispose);
|
|
|
}
|
|
|
|
|
|
- private static IAsyncEnumerator<T> Create<T>(Func<CancellationToken, TaskCompletionSource<bool>, Task<bool>> moveNext, Func<T> current, Action dispose)
|
|
|
+ private static IAsyncEnumerator<T> CreateEnumerator<T>(Func<CancellationToken, TaskCompletionSource<bool>, Task<bool>> moveNext, Func<T> current, Action dispose)
|
|
|
{
|
|
|
var self = default(IAsyncEnumerator<T>);
|
|
|
self = new AnonymousAsyncEnumerator<T>(
|
|
@@ -70,14 +57,15 @@ namespace System.Linq
|
|
|
var tcs = new TaskCompletionSource<bool>();
|
|
|
|
|
|
var stop = new Action(() =>
|
|
|
- {
|
|
|
- self.Dispose();
|
|
|
- tcs.TrySetCanceled();
|
|
|
- });
|
|
|
+ {
|
|
|
+ self.Dispose();
|
|
|
+ tcs.TrySetCanceled();
|
|
|
+ });
|
|
|
|
|
|
using (ct.Register(stop))
|
|
|
{
|
|
|
- return await moveNext(ct, tcs).ConfigureAwait(false);
|
|
|
+ return await moveNext(ct, tcs)
|
|
|
+ .ConfigureAwait(false);
|
|
|
}
|
|
|
},
|
|
|
current,
|
|
@@ -86,11 +74,26 @@ namespace System.Linq
|
|
|
return self;
|
|
|
}
|
|
|
|
|
|
+ private class AnonymousAsyncEnumerable<T> : IAsyncEnumerable<T>
|
|
|
+ {
|
|
|
+ private readonly Func<IAsyncEnumerator<T>> getEnumerator;
|
|
|
+
|
|
|
+ public AnonymousAsyncEnumerable(Func<IAsyncEnumerator<T>> getEnumerator)
|
|
|
+ {
|
|
|
+ this.getEnumerator = getEnumerator;
|
|
|
+ }
|
|
|
+
|
|
|
+ public IAsyncEnumerator<T> GetEnumerator()
|
|
|
+ {
|
|
|
+ return getEnumerator();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
private class AnonymousAsyncEnumerator<T> : IAsyncEnumerator<T>
|
|
|
{
|
|
|
- private readonly Func<CancellationToken, Task<bool>> _moveNext;
|
|
|
private readonly Func<T> _current;
|
|
|
private readonly Action _dispose;
|
|
|
+ private readonly Func<CancellationToken, Task<bool>> _moveNext;
|
|
|
private bool _disposed;
|
|
|
|
|
|
public AnonymousAsyncEnumerator(Func<CancellationToken, Task<bool>> moveNext, Func<T> current, Action dispose)
|
|
@@ -110,10 +113,7 @@ namespace System.Linq
|
|
|
|
|
|
public T Current
|
|
|
{
|
|
|
- get
|
|
|
- {
|
|
|
- return _current();
|
|
|
- }
|
|
|
+ get { return _current(); }
|
|
|
}
|
|
|
|
|
|
public void Dispose()
|
|
@@ -125,12 +125,5 @@ namespace System.Linq
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
}
|
|
|
-}
|
|
|
+}
|