Ejemplo n.º 1
0
        /// <summary>
        /// Retry the sequence until it terminates successfully, waiting <paramref name="waitTime"/> between retries.
        /// </summary>
        public static IAsyncEnumerable <T> Retry <T>(this IAsyncEnumerable <T> source, TimeSpan waitTime, ITime time)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (time is null)
            {
                time = Time.RealTime;
            }

            return(Create <T>(async(yield, token) =>
            {
                try
                {
                    // ReSharper disable once PossibleMultipleEnumeration
                    await source.CopyTo(yield, token).ConfigureAwait(false);
                    return;
                }
                catch { token.ThrowIfCancellationRequested(); }

                using var timer = time.GetTimer(token);
                while (true)
                {
                    try
                    {
                        await timer.Delay(waitTime).ConfigureAwait(false);
                        // ReSharper disable once PossibleMultipleEnumeration
                        await source.CopyTo(yield, token).ConfigureAwait(false);
                        return;
                    }
                    catch { token.ThrowIfCancellationRequested(); }
                }
            }));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Retry the sequence, waiting between retries for each element in <paramref name="waitTimes"/>.
        /// </summary>
        public static IAsyncEnumerable <T> Retry <T>(this IAsyncEnumerable <T> source, IEnumerable <TimeSpan> waitTimes, ITime time)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (waitTimes == null)
            {
                throw new ArgumentNullException(nameof(waitTimes));
            }
            if (time is null)
            {
                time = Time.RealTime;
            }

            return(Create <T>(async(yield, token) =>
            {
                Exception error;
                try
                {
                    // ReSharper disable once PossibleMultipleEnumeration
                    await source.CopyTo(yield, token).ConfigureAwait(false);
                    return;
                }
                catch (Exception ex)
                {
                    token.ThrowIfCancellationRequested();
                    error = ex;
                }

                using (var timer = time.GetTimer(token))
                    foreach (var waitTime in waitTimes)
                    {
                        try
                        {
                            await timer.Delay(waitTime).ConfigureAwait(false);
                            // ReSharper disable once PossibleMultipleEnumeration
                            await source.CopyTo(yield, token).ConfigureAwait(false);
                            return;
                        }
                        catch (Exception ex)
                        {
                            token.ThrowIfCancellationRequested();
                            error = ex;
                        }
                    }

                throw error;
            }));
        }
Ejemplo n.º 3
0
        public static async Task <Channel <T> > ToUnboundedChannel <T>(
            this IAsyncEnumerable <T> source,
            UnboundedChannelOptions?options,
            CancellationToken cancellationToken = default)
        {
            var channel = Channel.CreateUnbounded <T>(options ?? new UnboundedChannelOptions());
            await source.CopyTo(channel, ChannelCompletionMode.CompleteAndPropagateError, cancellationToken)
            .ConfigureAwait(false);

            return(channel);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Retry the sequence up to <paramref name="retryCount"/> times.
        /// </summary>
        public static IAsyncEnumerable <T> Retry <T>(this IAsyncEnumerable <T> source, int retryCount)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            return(Create <T>(async(yield, token) =>
            {
                Exception error;
                try
                {
                    // ReSharper disable once PossibleMultipleEnumeration
                    await source.CopyTo(yield, token).ConfigureAwait(false);
                    return;
                }
                catch (Exception ex)
                {
                    token.ThrowIfCancellationRequested();
                    error = ex;
                }

                for (var r = retryCount; r > 0; r--)
                {
                    try
                    {
                        // ReSharper disable once PossibleMultipleEnumeration
                        await source.CopyTo(yield, token).ConfigureAwait(false);
                        return;
                    }
                    catch (Exception ex)
                    {
                        token.ThrowIfCancellationRequested();
                        error = ex;
                    }
                }

                throw error;
            }));
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Catches exceptions of type <typeparamref name="TException"/>.
        /// </summary>
        public static IAsyncEnumerable <TSource> Catch <TSource, TException>(this IAsyncEnumerable <TSource> source) where TException : Exception
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            return(Create <TSource>(async(yield, token) =>
            {
                try { await source.CopyTo(yield, token).ConfigureAwait(false); }
                catch (TException) { /**/ }
            }));
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Invokes a specified async action after source observable sequence terminates normally or by an exception.
        /// </summary>
        public static IAsyncEnumerable <T> Finally <T>(this IAsyncEnumerable <T> source, Func <Task> @finally)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (@finally == null)
            {
                throw new ArgumentNullException(nameof(@finally));
            }

            return(Create <T>(async(yield, token) =>
            {
                try { await source.CopyTo(yield, token).ConfigureAwait(false); }
                finally { await @finally().ConfigureAwait(false); }
            }));
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Retry the sequence until it terminates successfully.
        /// </summary>
        public static IAsyncEnumerable <T> Retry <T>(this IAsyncEnumerable <T> source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            return(Create <T>(async(yield, token) =>
            {
                while (true)
                {
                    try
                    {
                        // ReSharper disable once PossibleMultipleEnumeration
                        await source.CopyTo(yield, token).ConfigureAwait(false);
                        return;
                    }
                    catch { token.ThrowIfCancellationRequested(); }
                }
            }));
        }