| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 | 
							- // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
 
- using System;
 
- using System.Collections.Generic;
 
- using System.Linq;
 
- using System.Threading;
 
- using System.Threading.Tasks;
 
- namespace System.Linq
 
- {
 
-     public static partial class AsyncEnumerable
 
-     {
 
-         static IAsyncEnumerable<T> Create<T>(Func<IAsyncEnumerator<T>> getEnumerator)
 
-         {
 
-             return new AnonymousAsyncEnumerable<T>(getEnumerator);
 
-         }
 
-         class AnonymousAsyncEnumerable<T> : IAsyncEnumerable<T>
 
-         {
 
-             Func<IAsyncEnumerator<T>> getEnumerator;
 
-             public AnonymousAsyncEnumerable(Func<IAsyncEnumerator<T>> getEnumerator)
 
-             {
 
-                 this.getEnumerator = getEnumerator;
 
-             }
 
-             public IAsyncEnumerator<T> GetEnumerator()
 
-             {
 
-                 return getEnumerator();
 
-             }
 
-         }
 
-         static IAsyncEnumerator<T> Create<T>(Func<CancellationToken, Task<bool>> moveNext, Func<T> current, Action dispose)
 
-         {
 
-             return new AnonymousAsyncEnumerator<T>(moveNext, current, dispose);
 
-         }
 
-         static IAsyncEnumerator<T> Create<T>(Func<CancellationToken, TaskCompletionSource<bool>, Task<bool>> moveNext, Func<T> current, Action dispose)
 
-         {
 
-             var self = default(IAsyncEnumerator<T>);
 
-             self = new AnonymousAsyncEnumerator<T>(
 
-                 ct =>
 
-                 {
 
-                     var tcs = new TaskCompletionSource<bool>();
 
-                     var stop = new Action(() =>
 
-                     {
 
-                         self.Dispose();
 
-                         tcs.TrySetCanceled();
 
-                     });
 
-                     var ctr = ct.Register(stop);
 
-                     var res = moveNext(ct, tcs).Finally(ctr.Dispose);
 
-                     return res;
 
-                 },
 
-                 current,
 
-                 dispose
 
-             );
 
-             return self;
 
-         }
 
-         class AnonymousAsyncEnumerator<T> : IAsyncEnumerator<T>
 
-         {
 
-             private readonly Func<CancellationToken, Task<bool>> _moveNext;
 
-             private readonly Func<T> _current;
 
-             private readonly Action _dispose;
 
-             private bool _disposed;
 
-             public AnonymousAsyncEnumerator(Func<CancellationToken, Task<bool>> moveNext, Func<T> current, Action dispose)
 
-             {
 
-                 _moveNext = moveNext;
 
-                 _current = current;
 
-                 _dispose = dispose;
 
-             }
 
-             public Task<bool> MoveNext(CancellationToken cancellationToken)
 
-             {
 
-                 if (_disposed)
 
-                     return TaskExt.Return(false, CancellationToken.None);
 
-                 return _moveNext(cancellationToken);
 
-             }
 
-             public T Current
 
-             {
 
-                 get
 
-                 {
 
-                     return _current();
 
-                 }
 
-             }
 
-             public void Dispose()
 
-             {
 
-                 if (!_disposed)
 
-                 {
 
-                     _disposed = true;
 
-                     _dispose();
 
-                 }
 
-             }
 
-         }
 
-         public static IAsyncEnumerable<TValue> Return<TValue>(TValue value)
 
-         {
 
-             return new[] { value }.ToAsyncEnumerable();
 
-         }
 
-         public static IAsyncEnumerable<TValue> Throw<TValue>(Exception exception)
 
-         {
 
-             if (exception == null)
 
-                 throw new ArgumentNullException("exception");
 
-             return Create(() => Create<TValue>(
 
-                 ct => TaskExt.Throw<bool>(exception, ct),
 
-                 () => { throw new InvalidOperationException(); },
 
-                 () => { })
 
-             );
 
-         }
 
-         public static IAsyncEnumerable<TValue> Never<TValue>()
 
-         {
 
-             return Create(() => Create<TValue>(
 
-                 (ct, tcs) => tcs.Task,
 
-                 () => { throw new InvalidOperationException(); },
 
-                 () => { })
 
-             );
 
-         }
 
-         public static IAsyncEnumerable<TValue> Empty<TValue>()
 
-         {
 
-             return Create(() => Create<TValue>(
 
-                 ct => TaskExt.Return(false, ct),
 
-                 () => { throw new InvalidOperationException(); },
 
-                 () => { })
 
-             );
 
-         }
 
-         public static IAsyncEnumerable<int> Range(int start, int count)
 
-         {
 
-             if (count < 0)
 
-                 throw new ArgumentOutOfRangeException("count");
 
-             return Enumerable.Range(start, count).ToAsyncEnumerable();
 
-         }
 
-         public static IAsyncEnumerable<TResult> Repeat<TResult>(TResult element, int count)
 
-         {
 
-             if (count < 0)
 
-                 throw new ArgumentOutOfRangeException("count");
 
-             return Enumerable.Repeat(element, count).ToAsyncEnumerable();
 
-         }
 
-         public static IAsyncEnumerable<TResult> Repeat<TResult>(TResult element)
 
-         {
 
-             return Create(() =>
 
-             {
 
-                 return Create(
 
-                     ct => TaskExt.Return(true, ct),
 
-                     () => element,
 
-                     () => { }
 
-                 );
 
-             });
 
-         }
 
-         public static IAsyncEnumerable<TSource> Defer<TSource>(Func<IAsyncEnumerable<TSource>> factory)
 
-         {
 
-             if (factory == null)
 
-                 throw new ArgumentNullException("factory");
 
-             return Create(() => factory().GetEnumerator());
 
-         }
 
-         public static IAsyncEnumerable<TResult> Generate<TState, TResult>(TState initialState, Func<TState, bool> condition, Func<TState, TState> iterate, Func<TState, TResult> resultSelector)
 
-         {
 
-             if (condition == null)
 
-                 throw new ArgumentNullException("condition");
 
-             if (iterate == null)
 
-                 throw new ArgumentNullException("iterate");
 
-             if (resultSelector == null)
 
-                 throw new ArgumentNullException("resultSelector");
 
-             return Create(() =>
 
-             {
 
-                 var i = initialState;
 
-                 var started = false;
 
-                 var current = default(TResult);
 
-                 return Create(
 
-                     ct =>
 
-                     {
 
-                         var b = false;
 
-                         try
 
-                         {
 
-                             if (started)
 
-                                 i = iterate(i);
 
-                             b = condition(i);
 
-                             if (b)
 
-                                 current = resultSelector(i);
 
-                         }
 
-                         catch (Exception ex)
 
-                         {
 
-                             return TaskExt.Throw<bool>(ex, ct);
 
-                         }
 
-                         if (!b)
 
-                             return TaskExt.Return(false, ct);
 
-                         if (!started)
 
-                             started = true;
 
-                         return TaskExt.Return(true, ct);
 
-                     },
 
-                     () => current,
 
-                     () => { }
 
-                 );
 
-             });
 
-         }
 
-         public static IAsyncEnumerable<TSource> Using<TSource, TResource>(Func<TResource> resourceFactory, Func<TResource, IAsyncEnumerable<TSource>> enumerableFactory) where TResource : IDisposable
 
-         {
 
-             if (resourceFactory == null)
 
-                 throw new ArgumentNullException("resourceFactory");
 
-             if (enumerableFactory == null)
 
-                 throw new ArgumentNullException("enumerableFactory");
 
-             return Create(() =>
 
-             {
 
-                 var resource = resourceFactory();
 
-                 var e = default(IAsyncEnumerator<TSource>);
 
-                 try
 
-                 {
 
-                     e = enumerableFactory(resource).GetEnumerator();
 
-                 }
 
-                 catch (Exception)
 
-                 {
 
-                     resource.Dispose();
 
-                     throw;
 
-                 }
 
-                 var cts = new CancellationTokenDisposable();
 
-                 var d = new CompositeDisposable(cts, resource, e);
 
-                 var current = default(TSource);
 
-                 return Create(
 
-                     (ct, tcs) =>
 
-                     {
 
-                         e.MoveNext(cts.Token).ContinueWith(t =>
 
-                         {
 
-                             t.Handle(tcs,
 
-                                 res =>
 
-                                 {
 
-                                     if (res)
 
-                                     {
 
-                                         current = e.Current;
 
-                                         tcs.TrySetResult(true);
 
-                                     }
 
-                                     else
 
-                                     {
 
-                                         d.Dispose();
 
-                                         tcs.TrySetResult(false);
 
-                                     }
 
-                                 },
 
-                                 ex =>
 
-                                 {
 
-                                     d.Dispose();
 
-                                     tcs.TrySetException(ex);
 
-                                 }
 
-                             );
 
-                         });
 
-                         return tcs.Task;
 
-                     },
 
-                     () => current,
 
-                     d.Dispose
 
-                 );
 
-             });
 
-         }
 
-     }
 
- }
 
 
  |