Write an Rx “RetryAfter” extension method

前端 未结 6 931
花落未央
花落未央 2020-11-27 16:00

In the book IntroToRx the author suggest to write a \"smart\" retry for I/O which retry an I/O request, like a network request, after a period of time.

Here is the e

6条回答
  •  萌比男神i
    2020-11-27 16:46

    Here's another slightly different implementation I came up with while studying how Rxx does it. So it's largely a cutdown version of Rxx's approach.

    The signature is slightly different from Markus' version. You specify a type of Exception to retry on, and the delay strategy takes the exception and the retry count, so you could have longer delays for each successive retry, etc.

    I can't guarantee it's bug proof, or the best approach, but it seems to work.

    public static IObservable RetryWithDelay(this IObservable source, Func delayFactory, IScheduler scheduler = null)
    where TException : Exception
    {
        return Observable.Create(observer =>
        {
            scheduler = scheduler ?? Scheduler.CurrentThread;
            var disposable = new SerialDisposable();
            int retryCount = 0;
    
            var scheduleDisposable = scheduler.Schedule(TimeSpan.Zero,
            self =>
            {
                var subscription = source.Subscribe(
                observer.OnNext,
                ex =>
                {
                    var typedException = ex as TException;
                    if (typedException != null)
                    {
                        var retryDelay = delayFactory(typedException, ++retryCount);
                        self(retryDelay);
                    }
                    else
                    {
                        observer.OnError(ex);
                    }
                },
                observer.OnCompleted);
    
                disposable.Disposable = subscription;
            });
    
            return new CompositeDisposable(scheduleDisposable, disposable);
        });
    }
    

提交回复
热议问题