public static IAsyncObservable <TSource> While <TSource>(Func <Task <bool> > condition, IAsyncObservable <TSource> source) { if (condition == null) { throw new ArgumentNullException(nameof(condition)); } if (source == null) { throw new ArgumentNullException(nameof(source)); } return(Create <TSource>(async observer => { var subscription = new SerialAsyncDisposable(); var o = default(IAsyncObserver <TSource>); o = AsyncObserver.CreateUnsafe <TSource>( observer.OnNextAsync, observer.OnErrorAsync, MoveNext ); async ValueTask MoveNext() { var b = default(bool); try { b = await condition().ConfigureAwait(false); } catch (Exception ex) { await observer.OnErrorAsync(ex).ConfigureAwait(false); return; } if (b) { var sad = new SingleAssignmentAsyncDisposable(); await subscription.AssignAsync(sad).ConfigureAwait(false); var d = await source.SubscribeSafeAsync(o).ConfigureAwait(false); await sad.AssignAsync(d).ConfigureAwait(false); } else { await observer.OnCompletedAsync().ConfigureAwait(false); } } await MoveNext().ConfigureAwait(false); return subscription; })); }
public static IAsyncObservable <TResult> For <TSource, TResult>(IEnumerable <TSource> source, Func <TSource, Task <IAsyncObservable <TResult> > > resultSelector) { if (source == null) { throw new ArgumentNullException(nameof(source)); } if (resultSelector == null) { throw new ArgumentNullException(nameof(resultSelector)); } return(Create <TResult>(async observer => { var subscription = new SerialAsyncDisposable(); var enumerator = source.GetEnumerator(); var o = default(IAsyncObserver <TResult>); o = AsyncObserver.CreateUnsafe <TResult>( observer.OnNextAsync, observer.OnErrorAsync, MoveNext ); async Task MoveNext() { var b = default(bool); var next = default(IAsyncObservable <TResult>); try { b = enumerator.MoveNext(); if (b) { next = await resultSelector(enumerator.Current).ConfigureAwait(false); } } catch (Exception ex) { await observer.OnErrorAsync(ex).ConfigureAwait(false); return; } if (b) { var sad = new SingleAssignmentAsyncDisposable(); await subscription.AssignAsync(sad).ConfigureAwait(false); var d = await next.SubscribeSafeAsync(o).ConfigureAwait(false); await sad.AssignAsync(d).ConfigureAwait(false); } else { await observer.OnCompletedAsync().ConfigureAwait(false); } } await MoveNext().ConfigureAwait(false); var disposeEnumerator = AsyncDisposable.Create(() => { enumerator.Dispose(); return Task.CompletedTask; }); return StableCompositeAsyncDisposable.Create(disposeEnumerator, subscription); })); }