<PackageReference Include="System.Reactive" Version="5.0.0" />

CatchScheduler<TException>

sealed class CatchScheduler<TException> : SchedulerWrapper where TException : Exception
using System.Reactive.Disposables; using System.Runtime.CompilerServices; namespace System.Reactive.Concurrency { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] internal sealed class CatchScheduler<[System.Runtime.CompilerServices.Nullable(0)] TException> : SchedulerWrapper where TException : Exception { [System.Runtime.CompilerServices.Nullable(0)] private class CatchSchedulerLongRunning : ISchedulerLongRunning { private readonly ISchedulerLongRunning _scheduler; private readonly Func<TException, bool> _handler; public CatchSchedulerLongRunning(ISchedulerLongRunning scheduler, Func<TException, bool> handler) { _scheduler = scheduler; _handler = handler; } public IDisposable ScheduleLongRunning<[System.Runtime.CompilerServices.Nullable(2)] TState>(TState state, Action<TState, ICancelable> action) { return this._scheduler.ScheduleLongRunning<TState>(state, (Action<TState, ICancelable>)delegate(TState state1, ICancelable cancel) { try { action(state1, cancel); } catch (TException val) when () { } }); } } [System.Runtime.CompilerServices.Nullable(0)] private sealed class CatchSchedulerPeriodic : ISchedulerPeriodic { [System.Runtime.CompilerServices.Nullable(0)] private sealed class PeriodicallyScheduledWorkItem<[System.Runtime.CompilerServices.Nullable(2)] TState> : IDisposable { private SingleAssignmentDisposableValue _cancel; private bool _failed; private readonly Func<TState, TState> _action; [System.Runtime.CompilerServices.Nullable(new byte[] { 1, 0 })] private readonly CatchSchedulerPeriodic _catchScheduler; public PeriodicallyScheduledWorkItem([System.Runtime.CompilerServices.Nullable(new byte[] { 1, 0 })] CatchSchedulerPeriodic scheduler, TState state, TimeSpan period, Func<TState, TState> action) { _catchScheduler = scheduler; _action = action; _cancel.Disposable = scheduler._scheduler.SchedulePeriodic<TState>(state, period, (Func<TState, TState>)((TState state1) => Tick(state1).state)); } public void Dispose() { _cancel.Dispose(); } [return: System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1, 0, 1, 1 })] private (PeriodicallyScheduledWorkItem<TState> this, TState state) Tick(TState state) { if (!_failed) try { return (this, _action(state)); } catch (TException val) { TException arg = (TException)val; _failed = true; if (!_catchScheduler._handler(arg)) throw; _cancel.Dispose(); return default((PeriodicallyScheduledWorkItem<TState>, TState)); } return default((PeriodicallyScheduledWorkItem<TState>, TState)); } } private readonly ISchedulerPeriodic _scheduler; private readonly Func<TException, bool> _handler; public CatchSchedulerPeriodic(ISchedulerPeriodic scheduler, Func<TException, bool> handler) { _scheduler = scheduler; _handler = handler; } public IDisposable SchedulePeriodic<[System.Runtime.CompilerServices.Nullable(2)] TState>(TState state, TimeSpan period, Func<TState, TState> action) { return new PeriodicallyScheduledWorkItem<TState>(this, state, period, action); } } private readonly Func<TException, bool> _handler; public CatchScheduler(IScheduler scheduler, Func<TException, bool> handler) : base(scheduler) { _handler = handler; } protected override Func<IScheduler, TState, IDisposable> Wrap<[System.Runtime.CompilerServices.Nullable(2)] TState>(Func<IScheduler, TState, IDisposable> action) { return delegate(IScheduler self, TState state) { try { return action(GetRecursiveWrapper(self), state); } catch (TException val) when () { return Disposable.Empty; } }; } public CatchScheduler(IScheduler scheduler, Func<TException, bool> handler, ConditionalWeakTable<IScheduler, IScheduler> cache) : base(scheduler, cache) { _handler = handler; } protected override SchedulerWrapper Clone(IScheduler scheduler, ConditionalWeakTable<IScheduler, IScheduler> cache) { return new CatchScheduler<TException>(scheduler, _handler, cache); } protected override bool TryGetService(IServiceProvider provider, Type serviceType, [System.Runtime.CompilerServices.Nullable(2)] out object service) { service = provider.GetService(serviceType); if (service != null) { if (serviceType == typeof(ISchedulerLongRunning)) service = new CatchSchedulerLongRunning((ISchedulerLongRunning)service, _handler); else if (serviceType == typeof(ISchedulerPeriodic)) { service = new CatchSchedulerPeriodic((ISchedulerPeriodic)service, _handler); } } return true; } } }