DispatcherScheduler
Represents an object that schedules units of work on a  Dispatcher.
            
                using System.Reactive.Disposables;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Windows.Threading;
namespace System.Reactive.Concurrency
{
    [System.Runtime.CompilerServices.NullableContext(1)]
    [System.Runtime.CompilerServices.Nullable(0)]
    public class DispatcherScheduler : LocalScheduler, ISchedulerPeriodic
    {
        [Obsolete("Use the Current property to retrieve the DispatcherScheduler instance for the current thread's Dispatcher object.")]
        public static DispatcherScheduler Instance {
            get {
                return new DispatcherScheduler(Dispatcher.get_CurrentDispatcher());
            }
        }
        public static DispatcherScheduler Current {
            get {
                Dispatcher val = Dispatcher.FromThread(Thread.CurrentThread);
                if ((int)val == 0)
                    throw new InvalidOperationException(Strings_WindowsThreading.NO_DISPATCHER_CURRENT_THREAD);
                return new DispatcherScheduler(val);
            }
        }
        public Dispatcher Dispatcher { get; }
        public DispatcherPriority Priority { get; }
        public DispatcherScheduler(Dispatcher dispatcher)
        {
            if (dispatcher == null)
                throw new ArgumentNullException("dispatcher");
            Dispatcher = dispatcher;
            Priority = 9;
        }
        public DispatcherScheduler(Dispatcher dispatcher, DispatcherPriority priority)
        {
            if (dispatcher == null)
                throw new ArgumentNullException("dispatcher");
            Dispatcher = dispatcher;
            Priority = priority;
        }
        public override IDisposable Schedule<[System.Runtime.CompilerServices.Nullable(2)] TState>(TState state, Func<IScheduler, TState, IDisposable> action)
        {
            if (action == null)
                throw new ArgumentNullException("action");
            SingleAssignmentDisposable d = new SingleAssignmentDisposable();
            Dispatcher.BeginInvoke((Delegate)(Action)delegate {
                if (!d.IsDisposed)
                    d.Disposable = action(this, state);
            }, Priority, Array.Empty<object>());
            return d;
        }
        public override IDisposable Schedule<[System.Runtime.CompilerServices.Nullable(2)] TState>(TState state, TimeSpan dueTime, Func<IScheduler, TState, IDisposable> action)
        {
            if (action == null)
                throw new ArgumentNullException("action");
            TimeSpan dueTime2 = Scheduler.Normalize(dueTime);
            if (dueTime2.Ticks == 0)
                return Schedule(state, action);
            return ScheduleSlow(state, dueTime2, action);
        }
        private IDisposable ScheduleSlow<[System.Runtime.CompilerServices.Nullable(2)] TState>(TState state, TimeSpan dueTime, Func<IScheduler, TState, IDisposable> action)
        {
            MultipleAssignmentDisposable d = new MultipleAssignmentDisposable();
            DispatcherTimer timer = new DispatcherTimer(Priority, Dispatcher);
            timer.add_Tick((EventHandler)delegate {
                DispatcherTimer val2 = Interlocked.Exchange<DispatcherTimer>(ref timer, null);
                if (val2 != null)
                    try {
                        d.Disposable = action(this, state);
                    } finally {
                        val2.Stop();
                        action = ((IScheduler s, TState t) => Disposable.Empty);
                    }
            });
            timer.set_Interval(dueTime);
            timer.Start();
            d.Disposable = Disposable.Create(delegate {
                DispatcherTimer val = Interlocked.Exchange<DispatcherTimer>(ref timer, null);
                if (val != null) {
                    val.Stop();
                    action = ((IScheduler s, TState t) => Disposable.Empty);
                }
            });
            return d;
        }
        public IDisposable SchedulePeriodic<[System.Runtime.CompilerServices.Nullable(2)] TState>(TState state, TimeSpan period, Func<TState, TState> action)
        {
            if (period < TimeSpan.Zero)
                throw new ArgumentOutOfRangeException("period");
            if (action == null)
                throw new ArgumentNullException("action");
            DispatcherTimer timer = new DispatcherTimer(Priority, Dispatcher);
            timer.add_Tick((EventHandler)delegate {
                state = action(state);
            });
            timer.set_Interval(period);
            timer.Start();
            return Disposable.Create(delegate {
                DispatcherTimer val = Interlocked.Exchange<DispatcherTimer>(ref timer, null);
                if (val != null) {
                    val.Stop();
                    action = ((TState _) => _);
                }
            });
        }
    }
}