Exemple #1
0
        public static ValueTask <IAsyncDisposable> Timer(IAsyncObserver <long> observer, DateTimeOffset dueTime, TimeSpan period, IAsyncScheduler scheduler)
        {
            if (period < TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException(nameof(period));
            }
            if (scheduler == null)
            {
                throw new ArgumentNullException(nameof(scheduler));
            }

            var tick = 0L;

            return(scheduler.ScheduleAsync(async ct =>
            {
                if (ct.IsCancellationRequested)
                {
                    return;
                }

                // TODO: Compensate for drift by adding stopwatch functionality.

                do
                {
                    await observer.OnNextAsync(tick++).RendezVous(scheduler, ct);

                    await scheduler.Delay(period, ct).RendezVous(scheduler, ct);
                } while (!ct.IsCancellationRequested);
            }, dueTime));
        }
 public static IAsyncObservable <int> ProduceSlowly(this IAsyncScheduler scheduler, params TimeSpan[] delays)
 {
     return(AsyncObservable.Range(0, delays.Length)
            .Select(async(i, ca) =>
     {
         await scheduler.Delay(delays[i], ca).ConfigureAwait(false);
         return i;
     }));
 }
Exemple #3
0
        public static Task <IAsyncDisposable> Generate <TState, TResult>(IAsyncObserver <TResult> observer, TState initialState, Func <TState, Task <bool> > condition, Func <TState, Task <TState> > iterate, Func <TState, Task <TResult> > resultSelector, Func <TState, Task <DateTimeOffset> > timeSelector, IAsyncScheduler scheduler)
        {
            if (observer == null)
            {
                throw new ArgumentNullException(nameof(observer));
            }
            if (condition == null)
            {
                throw new ArgumentNullException(nameof(condition));
            }
            if (iterate == null)
            {
                throw new ArgumentNullException(nameof(iterate));
            }
            if (resultSelector == null)
            {
                throw new ArgumentNullException(nameof(resultSelector));
            }
            if (timeSelector == null)
            {
                throw new ArgumentNullException(nameof(timeSelector));
            }
            if (scheduler == null)
            {
                throw new ArgumentNullException(nameof(scheduler));
            }

            return(scheduler.ScheduleAsync(async ct =>
            {
                var first = true;
                var state = initialState;

                while (!ct.IsCancellationRequested)
                {
                    var hasResult = false;
                    var result = default(TResult);
                    var nextDue = default(DateTimeOffset);

                    try
                    {
                        if (first)
                        {
                            first = false;
                        }
                        else
                        {
                            state = await iterate(state).RendezVous(scheduler, ct);
                        }

                        hasResult = await condition(state).RendezVous(scheduler, ct);

                        if (hasResult)
                        {
                            result = await resultSelector(state).RendezVous(scheduler, ct);
                            nextDue = await timeSelector(state).RendezVous(scheduler, ct);
                        }
                    }
                    catch (Exception ex)
                    {
                        await observer.OnErrorAsync(ex).RendezVous(scheduler, ct);
                        return;
                    }

                    if (hasResult)
                    {
                        await observer.OnNextAsync(result).RendezVous(scheduler, ct);
                    }
                    else
                    {
                        break;
                    }

                    await scheduler.Delay(nextDue).RendezVous(scheduler, ct);
                }

                if (!ct.IsCancellationRequested)
                {
                    await observer.OnCompletedAsync().RendezVous(scheduler, ct);
                }
            }));
        }