Răsfoiți Sursa

Misc. improvements to concurrency types

Bart De Smet 8 ani în urmă
părinte
comite
cf2ad6085b
44 a modificat fișierele cu 421 adăugiri și 609 ștergeri
  1. 4 1
      Rx.NET/Source/src/System.Reactive/Concurrency/AsyncLock.cs
  2. 9 10
      Rx.NET/Source/src/System.Reactive/Concurrency/CatchScheduler.cs
  3. 1 4
      Rx.NET/Source/src/System.Reactive/Concurrency/ConcurrencyAbstractionLayer.cs
  4. 4 18
      Rx.NET/Source/src/System.Reactive/Concurrency/ConcurrencyAbstractionLayerImpl.Windows.cs
  5. 11 43
      Rx.NET/Source/src/System.Reactive/Concurrency/ConcurrencyAbstractionLayerImpl.cs
  6. 14 30
      Rx.NET/Source/src/System.Reactive/Concurrency/CurrentThreadScheduler.cs
  7. 10 12
      Rx.NET/Source/src/System.Reactive/Concurrency/DefaultScheduler.cs
  8. 1 1
      Rx.NET/Source/src/System.Reactive/Concurrency/DisableOptimizationsScheduler.cs
  9. 7 5
      Rx.NET/Source/src/System.Reactive/Concurrency/EventLoopScheduler.cs
  10. 19 19
      Rx.NET/Source/src/System.Reactive/Concurrency/HistoricalScheduler.cs
  11. 1 1
      Rx.NET/Source/src/System.Reactive/Concurrency/IScheduler.cs
  12. 1 1
      Rx.NET/Source/src/System.Reactive/Concurrency/ISchedulerLongRunning.cs
  13. 0 2
      Rx.NET/Source/src/System.Reactive/Concurrency/ISchedulerPeriodic.cs
  14. 0 2
      Rx.NET/Source/src/System.Reactive/Concurrency/IStopwatch.cs
  15. 1 3
      Rx.NET/Source/src/System.Reactive/Concurrency/IStopwatchProvider.cs
  16. 21 9
      Rx.NET/Source/src/System.Reactive/Concurrency/ImmediateScheduler.cs
  17. 15 30
      Rx.NET/Source/src/System.Reactive/Concurrency/LocalScheduler.TimerQueue.cs
  18. 8 17
      Rx.NET/Source/src/System.Reactive/Concurrency/LocalScheduler.cs
  19. 7 13
      Rx.NET/Source/src/System.Reactive/Concurrency/NewThreadScheduler.cs
  20. 32 58
      Rx.NET/Source/src/System.Reactive/Concurrency/ScheduledItem.cs
  21. 23 25
      Rx.NET/Source/src/System.Reactive/Concurrency/Scheduler.Async.cs
  22. 22 10
      Rx.NET/Source/src/System.Reactive/Concurrency/Scheduler.Recursive.cs
  23. 23 14
      Rx.NET/Source/src/System.Reactive/Concurrency/Scheduler.Services.Emulation.cs
  24. 23 32
      Rx.NET/Source/src/System.Reactive/Concurrency/Scheduler.Services.cs
  25. 5 5
      Rx.NET/Source/src/System.Reactive/Concurrency/Scheduler.Simple.cs
  26. 3 3
      Rx.NET/Source/src/System.Reactive/Concurrency/Scheduler.Wrappers.cs
  27. 11 58
      Rx.NET/Source/src/System.Reactive/Concurrency/Scheduler.cs
  28. 5 5
      Rx.NET/Source/src/System.Reactive/Concurrency/SchedulerDefaults.cs
  29. 5 15
      Rx.NET/Source/src/System.Reactive/Concurrency/SchedulerOperation.cs
  30. 5 20
      Rx.NET/Source/src/System.Reactive/Concurrency/SchedulerQueue.cs
  31. 1 4
      Rx.NET/Source/src/System.Reactive/Concurrency/SchedulerWrapper.cs
  32. 8 8
      Rx.NET/Source/src/System.Reactive/Concurrency/Synchronization.ObserveOn.cs
  33. 7 7
      Rx.NET/Source/src/System.Reactive/Concurrency/Synchronization.Synchronize.cs
  34. 8 6
      Rx.NET/Source/src/System.Reactive/Concurrency/Synchronization.cs
  35. 8 4
      Rx.NET/Source/src/System.Reactive/Concurrency/SynchronizationContextScheduler.cs
  36. 1 1
      Rx.NET/Source/src/System.Reactive/Concurrency/TaskHelpers.cs
  37. 18 15
      Rx.NET/Source/src/System.Reactive/Concurrency/TaskPoolScheduler.cs
  38. 6 7
      Rx.NET/Source/src/System.Reactive/Concurrency/Thread.Stub.cs
  39. 21 25
      Rx.NET/Source/src/System.Reactive/Concurrency/ThreadPoolScheduler.Windows.cs
  40. 17 28
      Rx.NET/Source/src/System.Reactive/Concurrency/ThreadPoolScheduler.cs
  41. 5 5
      Rx.NET/Source/src/System.Reactive/Concurrency/VirtualTimeScheduler.Extensions.cs
  42. 28 31
      Rx.NET/Source/src/System.Reactive/Concurrency/VirtualTimeScheduler.cs
  43. 1 1
      Rx.NET/Source/src/System.Reactive/Platforms/Windows/Concurrency/CoreDispatcherScheduler.cs
  44. 1 1
      Rx.NET/Source/src/System.Reactive/Platforms/Windows/Concurrency/DispatcherScheduler.cs

+ 4 - 1
Rx.NET/Source/src/System.Reactive/Concurrency/AsyncLock.cs

@@ -21,7 +21,7 @@ namespace System.Reactive.Concurrency
         /// processed by the owner.
         /// </summary>
         /// <param name="action">Action to queue for execution.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
         public void Wait(Action action)
         {
             if (action == null)
@@ -46,7 +46,9 @@ namespace System.Reactive.Concurrency
                     lock (queue)
                     {
                         if (queue.Count > 0)
+                        {
                             work = queue.Dequeue();
+                        }
                         else
                         {
                             isAcquired = false;
@@ -65,6 +67,7 @@ namespace System.Reactive.Concurrency
                             queue.Clear();
                             hasFaulted = true;
                         }
+
                         throw;
                     }
                 }

+ 9 - 10
Rx.NET/Source/src/System.Reactive/Concurrency/CatchScheduler.cs

@@ -7,7 +7,7 @@ using System.Runtime.CompilerServices;
 
 namespace System.Reactive.Concurrency
 {
-    class CatchScheduler<TException> : SchedulerWrapper
+    internal sealed class CatchScheduler<TException> : SchedulerWrapper
         where TException : Exception
     {
         private readonly Func<TException, bool> _handler;
@@ -26,11 +26,8 @@ namespace System.Reactive.Concurrency
                 {
                     return action(GetRecursiveWrapper(self), state);
                 }
-                catch (TException exception)
+                catch (TException exception) when (_handler(exception))
                 {
-                    if (!_handler(exception))
-                        throw;
-
                     return Disposable.Empty;
                 }
             };
@@ -54,15 +51,19 @@ namespace System.Reactive.Concurrency
             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;
         }
 
-        class CatchSchedulerLongRunning : ISchedulerLongRunning
+        private class CatchSchedulerLongRunning : ISchedulerLongRunning
         {
             private readonly ISchedulerLongRunning _scheduler;
             private readonly Func<TException, bool> _handler;
@@ -81,16 +82,14 @@ namespace System.Reactive.Concurrency
                     {
                         action(state_, cancel);
                     }
-                    catch (TException exception)
+                    catch (TException exception) when (_handler(exception))
                     {
-                        if (!_handler(exception))
-                            throw;
                     }
                 });
             }
         }
 
-        class CatchSchedulerPeriodic : ISchedulerPeriodic
+        private sealed class CatchSchedulerPeriodic : ISchedulerPeriodic
         {
             private readonly ISchedulerPeriodic _scheduler;
             private readonly Func<TException, bool> _handler;

+ 1 - 4
Rx.NET/Source/src/System.Reactive/Concurrency/ConcurrencyAbstractionLayer.cs

@@ -75,10 +75,7 @@ namespace System.Reactive.Concurrency
         /// <summary>
         /// Gets whether long-running scheduling is supported.
         /// </summary>
-        bool SupportsLongRunning
-        {
-            get;
-        }
+        bool SupportsLongRunning { get; }
 
         /// <summary>
         /// Starts a new long-running thread.

+ 4 - 18
Rx.NET/Source/src/System.Reactive/Concurrency/ConcurrencyAbstractionLayerImpl.Windows.cs

@@ -3,8 +3,6 @@
 // See the LICENSE file in the project root for more information. 
 
 #if NO_THREAD && WINDOWS
-using System;
-using System.Collections.Generic;
 using System.Reactive.Disposables;
 using System.Threading;
 
@@ -72,28 +70,16 @@ namespace System.Reactive.Concurrency
             e.Wait();
         }
 
-        public IStopwatch StartStopwatch()
-        {
-            return new StopwatchImpl();
-        }
+        public IStopwatch StartStopwatch() => new StopwatchImpl();
 
-        public bool SupportsLongRunning
-        {
-            get { return false; }
-        }
+        public bool SupportsLongRunning => false;
 
         public void StartThread(Action<object> action, object state)
         {
             throw new NotSupportedException();
         }
 
-        private TimeSpan Normalize(TimeSpan dueTime)
-        {
-            if (dueTime < TimeSpan.Zero)
-                return TimeSpan.Zero;
-
-            return dueTime;
-        }
+        private TimeSpan Normalize(TimeSpan dueTime) => dueTime < TimeSpan.Zero ? TimeSpan.Zero : dueTime;
     }
 }
-#endif
+#endif

+ 11 - 43
Rx.NET/Source/src/System.Reactive/Concurrency/ConcurrencyAbstractionLayerImpl.cs

@@ -3,7 +3,6 @@
 // See the LICENSE file in the project root for more information. 
 
 #if !NO_THREAD
-using System;
 using System.Collections.Generic;
 using System.Reactive.Disposables;
 using System.Threading;
@@ -17,10 +16,7 @@ namespace System.Reactive.Concurrency
     //
     internal class /*Default*/ConcurrencyAbstractionLayerImpl : IConcurrencyAbstractionLayer
     {
-        public IDisposable StartTimer(Action<object> action, object state, TimeSpan dueTime)
-        {
-            return new Timer(action, state, Normalize(dueTime));
-        }
+        public IDisposable StartTimer(Action<object> action, object state, TimeSpan dueTime) => new Timer(action, state, Normalize(dueTime));
 
         public IDisposable StartPeriodicTimer(Action action, TimeSpan period)
         {
@@ -47,27 +43,11 @@ namespace System.Reactive.Concurrency
             return Disposable.Empty;
         }
 
-#if USE_SLEEP_MS
-        public void Sleep(TimeSpan timeout)
-        {
-            System.Threading.Thread.Sleep((int)Normalize(timeout).TotalMilliseconds);
-        }
-#else
-        public void Sleep(TimeSpan timeout)
-        {
-            System.Threading.Thread.Sleep(Normalize(timeout));
-        }
-#endif
+        public void Sleep(TimeSpan timeout) => System.Threading.Thread.Sleep(Normalize(timeout));
 
-        public IStopwatch StartStopwatch()
-        {
-            return new StopwatchImpl();
-        }
+        public IStopwatch StartStopwatch() => new StopwatchImpl();
 
-        public bool SupportsLongRunning
-        {
-            get { return true; }
-        }
+        public bool SupportsLongRunning => true;
 
         public void StartThread(Action<object> action, object state)
         {
@@ -77,13 +57,7 @@ namespace System.Reactive.Concurrency
             }) { IsBackground = true }.Start();
         }
 
-        private static TimeSpan Normalize(TimeSpan dueTime)
-        {
-            if (dueTime < TimeSpan.Zero)
-                return TimeSpan.Zero;
-
-            return dueTime;
-        }
+        private static TimeSpan Normalize(TimeSpan dueTime) => dueTime < TimeSpan.Zero ? TimeSpan.Zero : dueTime;
 
         //
         // Some historical context. In the early days of Rx, we discovered an issue with
@@ -156,7 +130,7 @@ namespace System.Reactive.Concurrency
         //                 symbol.
         //
 
-        class Timer : IDisposable
+        private sealed class Timer : IDisposable
         {
             private Action<object> _action;
             private volatile System.Threading.Timer _timer;
@@ -190,10 +164,7 @@ namespace System.Reactive.Concurrency
                 }
             }
 
-            private bool IsTimerAssigned()
-            {
-                return _timer != null;
-            }
+            private bool IsTimerAssigned() => _timer != null;
 
             public void Dispose()
             {
@@ -208,7 +179,7 @@ namespace System.Reactive.Concurrency
             }
         }
 
-        class PeriodicTimer : IDisposable
+        private sealed class PeriodicTimer : IDisposable
         {
             private Action _action;
             private volatile System.Threading.Timer _timer;
@@ -224,10 +195,7 @@ namespace System.Reactive.Concurrency
                 _timer = new System.Threading.Timer(this.Tick, null, period, period);
             }
 
-            private void Tick(object state)
-            {
-                _action();
-            }
+            private void Tick(object state) => _action();
 
             public void Dispose()
             {
@@ -242,7 +210,7 @@ namespace System.Reactive.Concurrency
             }
         }
 
-        class FastPeriodicTimer : IDisposable
+        private sealed class FastPeriodicTimer : IDisposable
         {
             private readonly Action _action;
             private volatile bool disposed;
@@ -274,4 +242,4 @@ namespace System.Reactive.Concurrency
         }
     }
 }
-#endif
+#endif

+ 14 - 30
Rx.NET/Source/src/System.Reactive/Concurrency/CurrentThreadScheduler.cs

@@ -16,28 +16,22 @@ namespace System.Reactive.Concurrency
     {
         private static readonly Lazy<CurrentThreadScheduler> s_instance = new Lazy<CurrentThreadScheduler>(() => new CurrentThreadScheduler());
 
-        CurrentThreadScheduler()
+        private CurrentThreadScheduler()
         {
         }
 
         /// <summary>
         /// Gets the singleton instance of the current thread scheduler.
         /// </summary>
-        public static CurrentThreadScheduler Instance
-        {
-            get { return s_instance.Value; }
-        }
+        public static CurrentThreadScheduler Instance => s_instance.Value;
 
         [ThreadStatic]
-        static SchedulerQueue<TimeSpan> s_threadLocalQueue;
+        private static SchedulerQueue<TimeSpan> s_threadLocalQueue;
 
         [ThreadStatic]
-        static IStopwatch s_clock;
+        private static IStopwatch s_clock;
 
-        private static SchedulerQueue<TimeSpan> GetQueue()
-        {
-            return s_threadLocalQueue;
-        }
+        private static SchedulerQueue<TimeSpan> GetQueue() => s_threadLocalQueue;
 
         private static void SetQueue(SchedulerQueue<TimeSpan> newQueue)
         {
@@ -61,25 +55,13 @@ namespace System.Reactive.Concurrency
         [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Now marked as obsolete.")]
         [EditorBrowsable(EditorBrowsableState.Never)]
         [Obsolete(Constants_Core.OBSOLETE_SCHEDULEREQUIRED)] // Preferring static method call over instance method call.
-        public bool ScheduleRequired
-        {
-            get
-            {
-                return IsScheduleRequired;
-            }
-        }
+        public bool ScheduleRequired => IsScheduleRequired;
 
         /// <summary>
         /// Gets a value that indicates whether the caller must call a Schedule method.
         /// </summary>
         [EditorBrowsable(EditorBrowsableState.Advanced)]
-        public static bool IsScheduleRequired
-        {
-            get
-            {
-                return GetQueue() == null;
-            }
-        }
+        public static bool IsScheduleRequired => GetQueue() == null;
 
         /// <summary>
         /// Schedules an action to be executed after dueTime.
@@ -89,7 +71,7 @@ namespace System.Reactive.Concurrency
         /// <param name="action">Action to be executed.</param>
         /// <param name="dueTime">Relative time after which to execute the action.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
         public override IDisposable Schedule<TState>(TState state, TimeSpan dueTime, Func<IScheduler, TState, IDisposable> action)
         {
             if (action == null)
@@ -106,14 +88,14 @@ namespace System.Reactive.Concurrency
                 queue = new SchedulerQueue<TimeSpan>(4);
                 queue.Enqueue(si);
 
-                CurrentThreadScheduler.SetQueue(queue);
+                SetQueue(queue);
                 try
                 {
                     Trampoline.Run(queue);
                 }
                 finally
                 {
-                    CurrentThreadScheduler.SetQueue(null);
+                    SetQueue(null);
                 }
             }
             else
@@ -124,7 +106,7 @@ namespace System.Reactive.Concurrency
             return Disposable.Create(si.Cancel);
         }
 
-        static class Trampoline
+        private static class Trampoline
         {
             public static void Run(SchedulerQueue<TimeSpan> queue)
             {
@@ -133,14 +115,16 @@ namespace System.Reactive.Concurrency
                     var item = queue.Dequeue();
                     if (!item.IsCanceled)
                     {
-                        var wait = item.DueTime - CurrentThreadScheduler.Time;
+                        var wait = item.DueTime - Time;
                         if (wait.Ticks > 0)
                         {
                             ConcurrencyAbstractionLayer.Current.Sleep(wait);
                         }
 
                         if (!item.IsCanceled)
+                        {
                             item.Invoke();
+                        }
                     }
                 }
             }

+ 10 - 12
Rx.NET/Source/src/System.Reactive/Concurrency/DefaultScheduler.cs

@@ -18,13 +18,7 @@ namespace System.Reactive.Concurrency
         /// <summary>
         /// Gets the singleton instance of the default scheduler.
         /// </summary>
-        public static DefaultScheduler Instance
-        {
-            get
-            {
-                return s_instance.Value;
-            }
-        }
+        public static DefaultScheduler Instance => s_instance.Value;
 
         private DefaultScheduler()
         {
@@ -37,7 +31,7 @@ namespace System.Reactive.Concurrency
         /// <param name="state">State passed to the action to be executed.</param>
         /// <param name="action">Action to be executed.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
         public override IDisposable Schedule<TState>(TState state, Func<IScheduler, TState, IDisposable> action)
         {
             if (action == null)
@@ -48,7 +42,9 @@ namespace System.Reactive.Concurrency
             var cancel = s_cal.QueueUserWorkItem(_ =>
             {
                 if (!d.IsDisposed)
+                {
                     d.Disposable = action(this, state);
+                }
             }, null);
 
             return StableCompositeDisposable.Create(
@@ -65,7 +61,7 @@ namespace System.Reactive.Concurrency
         /// <param name="action">Action to be executed.</param>
         /// <param name="dueTime">Relative time after which to execute the action.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
         public override IDisposable Schedule<TState>(TState state, TimeSpan dueTime, Func<IScheduler, TState, IDisposable> action)
         {
             if (action == null)
@@ -80,7 +76,9 @@ namespace System.Reactive.Concurrency
             var cancel = s_cal.StartTimer(_ =>
             {
                 if (!d.IsDisposed)
+                {
                     d.Disposable = action(this, state);
+                }
             }, null, dt);
 
             return StableCompositeDisposable.Create(
@@ -97,8 +95,8 @@ namespace System.Reactive.Concurrency
         /// <param name="period">Period for running the work periodically.</param>
         /// <param name="action">Action to be executed, potentially updating the state.</param>
         /// <returns>The disposable object used to cancel the scheduled recurring action (best effort).</returns>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="period"/> is less than TimeSpan.Zero.</exception>
-        /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="period"/> is less than <see cref="TimeSpan.Zero"/>.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
         public IDisposable SchedulePeriodic<TState>(TState state, TimeSpan period, Func<TState, TState> action)
         {
             if (period < TimeSpan.Zero)
@@ -143,7 +141,7 @@ namespace System.Reactive.Concurrency
             return base.GetService(serviceType);
         }
 
-        class LongRunning : ISchedulerLongRunning
+        private sealed class LongRunning : ISchedulerLongRunning
         {
             public static ISchedulerLongRunning Instance = new LongRunning();
 

+ 1 - 1
Rx.NET/Source/src/System.Reactive/Concurrency/DisableOptimizationsScheduler.cs

@@ -7,7 +7,7 @@ using System.Runtime.CompilerServices;
 
 namespace System.Reactive.Concurrency
 {
-    class DisableOptimizationsScheduler : SchedulerWrapper
+    internal sealed class DisableOptimizationsScheduler : SchedulerWrapper
     {
         private readonly Type[] _optimizationInterfaces;
 

+ 7 - 5
Rx.NET/Source/src/System.Reactive/Concurrency/EventLoopScheduler.cs

@@ -91,7 +91,7 @@ namespace System.Reactive.Concurrency
         /// Creates an object that schedules units of work on a designated thread, using the specified factory to control thread creation options.
         /// </summary>
         /// <param name="threadFactory">Factory function for thread creation.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="threadFactory"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="threadFactory"/> is <c>null</c>.</exception>
         public EventLoopScheduler(Func<ThreadStart, Thread> threadFactory)
         {
             if (threadFactory == null)
@@ -141,7 +141,7 @@ namespace System.Reactive.Concurrency
         /// <param name="action">Action to be executed.</param>
         /// <param name="dueTime">Relative time after which to execute the action.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
         /// <exception cref="ObjectDisposedException">The scheduler has been disposed and doesn't accept new work.</exception>
         public override IDisposable Schedule<TState>(TState state, TimeSpan dueTime, Func<IScheduler, TState, IDisposable> action)
         {
@@ -181,8 +181,8 @@ namespace System.Reactive.Concurrency
         /// <param name="period">Period for running the work periodically.</param>
         /// <param name="action">Action to be executed, potentially updating the state.</param>
         /// <returns>The disposable object used to cancel the scheduled recurring action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="period"/> is less than TimeSpan.Zero.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="period"/> is less than <see cref="TimeSpan.Zero"/>.</exception>
         /// <exception cref="ObjectDisposedException">The scheduler has been disposed and doesn't accept new work.</exception>
         public IDisposable SchedulePeriodic<TState>(TState state, TimeSpan period, Func<TState, TState> action)
         {
@@ -325,7 +325,9 @@ namespace System.Reactive.Concurrency
                     foreach (var item in ready)
                     {
                         if (!item.IsCanceled)
+                        {
                             item.Invoke();
+                        }
                     }
                 }
 
@@ -362,4 +364,4 @@ namespace System.Reactive.Concurrency
 
         #endregion
     }
-}
+}

+ 19 - 19
Rx.NET/Source/src/System.Reactive/Concurrency/HistoricalScheduler.cs

@@ -8,12 +8,12 @@ using System.Reactive.Disposables;
 namespace System.Reactive.Concurrency
 {
     /// <summary>
-    /// Base class for historical schedulers, which are virtual time schedulers that use DateTimeOffset for absolute time and TimeSpan for relative time.
+    /// Base class for historical schedulers, which are virtual time schedulers that use <see cref="DateTimeOffset"/> for absolute time and <see cref="TimeSpan"/> for relative time.
     /// </summary>
     public abstract class HistoricalSchedulerBase : VirtualTimeSchedulerBase<DateTimeOffset, TimeSpan>
     {
         /// <summary>
-        /// Creates a new historical scheduler with the minimum value of DateTimeOffset as the initial clock value.
+        /// Creates a new historical scheduler with the minimum value of <see cref="DateTimeOffset"/> as the initial clock value.
         /// </summary>
         protected HistoricalSchedulerBase()
             : base(DateTimeOffset.MinValue, Comparer<DateTimeOffset>.Default)
@@ -51,35 +51,29 @@ namespace System.Reactive.Concurrency
         }
 
         /// <summary>
-        /// Converts the absolute time value to a DateTimeOffset value.
+        /// Converts the absolute time value to a <see cref="DateTimeOffset"/> value.
         /// </summary>
         /// <param name="absolute">Absolute time value to convert.</param>
-        /// <returns>The corresponding DateTimeOffset value.</returns>
-        protected override DateTimeOffset ToDateTimeOffset(DateTimeOffset absolute)
-        {
-            return absolute;
-        }
+        /// <returns>The corresponding <see cref="DateTimeOffset"/> value.</returns>
+        protected override DateTimeOffset ToDateTimeOffset(DateTimeOffset absolute) => absolute;
 
         /// <summary>
-        /// Converts the TimeSpan value to a relative time value.
+        /// Converts the <see cref="TimeSpan"/> value to a relative time value.
         /// </summary>
-        /// <param name="timeSpan">TimeSpan value to convert.</param>
+        /// <param name="timeSpan"><see cref="TimeSpan"/> value to convert.</param>
         /// <returns>The corresponding relative time value.</returns>
-        protected override TimeSpan ToRelative(TimeSpan timeSpan)
-        {
-            return timeSpan;
-        }
+        protected override TimeSpan ToRelative(TimeSpan timeSpan) => timeSpan;
     }
 
     /// <summary>
-    /// Provides a virtual time scheduler that uses DateTimeOffset for absolute time and TimeSpan for relative time.
+    /// Provides a virtual time scheduler that uses <see cref="DateTimeOffset"/> for absolute time and <see cref="TimeSpan"/> for relative time.
     /// </summary>
     public class HistoricalScheduler : HistoricalSchedulerBase
     {
         private readonly SchedulerQueue<DateTimeOffset> queue = new SchedulerQueue<DateTimeOffset>();
 
         /// <summary>
-        /// Creates a new historical scheduler with the minimum value of DateTimeOffset as the initial clock value.
+        /// Creates a new historical scheduler with the minimum value of <see cref="DateTimeOffset"/> as the initial clock value.
         /// </summary>
         public HistoricalScheduler()
             : base()
@@ -100,7 +94,7 @@ namespace System.Reactive.Concurrency
         /// </summary>
         /// <param name="initialClock">Initial value for the clock.</param>
         /// <param name="comparer">Comparer to determine causality of events based on absolute time.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="comparer"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="comparer"/> is <c>null</c>.</exception>
         public HistoricalScheduler(DateTimeOffset initialClock, IComparer<DateTimeOffset> comparer)
             : base(initialClock, comparer)
         {
@@ -115,23 +109,29 @@ namespace System.Reactive.Concurrency
             while (queue.Count > 0)
             {
                 var next = queue.Peek();
+
                 if (next.IsCanceled)
+                {
                     queue.Dequeue();
+                }
                 else
+                {
                     return next;
+                }
             }
+
             return null;
         }
 
         /// <summary>
-        /// Schedules an action to be executed at dueTime.
+        /// Schedules an action to be executed at <paramref name="dueTime"/>.
         /// </summary>
         /// <typeparam name="TState">The type of the state passed to the scheduled action.</typeparam>
         /// <param name="state">State passed to the action to be executed.</param>
         /// <param name="action">Action to be executed.</param>
         /// <param name="dueTime">Absolute time at which to execute the action.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
         public override IDisposable ScheduleAbsolute<TState>(TState state, DateTimeOffset dueTime, Func<IScheduler, TState, IDisposable> action)
         {
             if (action == null)

+ 1 - 1
Rx.NET/Source/src/System.Reactive/Concurrency/IScheduler.cs

@@ -43,4 +43,4 @@ namespace System.Reactive.Concurrency
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
         IDisposable Schedule<TState>(TState state, DateTimeOffset dueTime, Func<IScheduler, TState, IDisposable> action);
     }
-}
+}

+ 1 - 1
Rx.NET/Source/src/System.Reactive/Concurrency/ISchedulerLongRunning.cs

@@ -25,4 +25,4 @@ namespace System.Reactive.Concurrency
         /// </remarks>
         IDisposable ScheduleLongRunning<TState>(TState state, Action<TState, ICancelable> action);
     }
-}
+}

+ 0 - 2
Rx.NET/Source/src/System.Reactive/Concurrency/ISchedulerPeriodic.cs

@@ -2,8 +2,6 @@
 // The .NET Foundation licenses this file to you under the Apache 2.0 License.
 // See the LICENSE file in the project root for more information. 
 
-using System.Reactive.Disposables;
-
 namespace System.Reactive.Concurrency
 {
     /// <summary>

+ 0 - 2
Rx.NET/Source/src/System.Reactive/Concurrency/IStopwatch.cs

@@ -2,8 +2,6 @@
 // The .NET Foundation licenses this file to you under the Apache 2.0 License.
 // See the LICENSE file in the project root for more information. 
 
-using System;
-
 namespace System.Reactive.Concurrency
 {
     /// <summary>

+ 1 - 3
Rx.NET/Source/src/System.Reactive/Concurrency/IStopwatchProvider.cs

@@ -2,8 +2,6 @@
 // The .NET Foundation licenses this file to you under the Apache 2.0 License.
 // See the LICENSE file in the project root for more information. 
 
-using System;
-
 namespace System.Reactive.Concurrency
 {
     /*
@@ -14,7 +12,7 @@ namespace System.Reactive.Concurrency
      */
 
     /// <summary>
-    /// Provider for IStopwatch objects.
+    /// Provider for <see cref="IStopwatch"/> objects.
     /// </summary>
     public interface IStopwatchProvider
     {

+ 21 - 9
Rx.NET/Source/src/System.Reactive/Concurrency/ImmediateScheduler.cs

@@ -2,7 +2,6 @@
 // The .NET Foundation licenses this file to you under the Apache 2.0 License.
 // See the LICENSE file in the project root for more information. 
 
-using System.Threading;
 using System.Reactive.Disposables;
 
 namespace System.Reactive.Concurrency
@@ -15,17 +14,14 @@ namespace System.Reactive.Concurrency
     {
         private static readonly Lazy<ImmediateScheduler> s_instance = new Lazy<ImmediateScheduler>(() => new ImmediateScheduler());
 
-        ImmediateScheduler()
+        private ImmediateScheduler()
         {
         }
 
         /// <summary>
         /// Gets the singleton instance of the immediate scheduler.
         /// </summary>
-        public static ImmediateScheduler Instance
-        {
-            get { return s_instance.Value; }
-        }
+        public static ImmediateScheduler Instance => s_instance.Value;
 
         /// <summary>
         /// Schedules an action to be executed.
@@ -66,9 +62,9 @@ namespace System.Reactive.Concurrency
             return action(new AsyncLockScheduler(), state);
         }
 
-        class AsyncLockScheduler : LocalScheduler
+        private sealed class AsyncLockScheduler : LocalScheduler
         {
-            AsyncLock asyncLock;
+            private AsyncLock asyncLock;
 
             public override IDisposable Schedule<TState>(TState state, Func<IScheduler, TState, IDisposable> action)
             {
@@ -78,12 +74,16 @@ namespace System.Reactive.Concurrency
                 var m = new SingleAssignmentDisposable();
 
                 if (asyncLock == null)
+                {
                     asyncLock = new AsyncLock();
+                }
 
                 asyncLock.Wait(() =>
                 {
                     if (!m.IsDisposed)
+                    {
                         m.Disposable = action(this, state);
+                    }
                 });
 
                 return m;
@@ -95,14 +95,23 @@ namespace System.Reactive.Concurrency
                     throw new ArgumentNullException(nameof(action));
 
                 if (dueTime.Ticks <= 0)
-                    return Schedule<TState>(state, action);
+                {
+                    return Schedule(state, action);
+                }
 
+                return ScheduleSlow(state, dueTime, action);
+            }
+
+            private IDisposable ScheduleSlow<TState>(TState state, TimeSpan dueTime, Func<IScheduler, TState, IDisposable> action)
+            {
                 var timer = ConcurrencyAbstractionLayer.Current.StartStopwatch();
 
                 var m = new SingleAssignmentDisposable();
 
                 if (asyncLock == null)
+                {
                     asyncLock = new AsyncLock();
+                }
 
                 asyncLock.Wait(() =>
                 {
@@ -113,8 +122,11 @@ namespace System.Reactive.Concurrency
                         {
                             ConcurrencyAbstractionLayer.Current.Sleep(sleep);
                         }
+
                         if (!m.IsDisposed)
+                        {
                             m.Disposable = action(this, state);
+                        }
                     }
                 });
 

+ 15 - 30
Rx.NET/Source/src/System.Reactive/Concurrency/LocalScheduler.TimerQueue.cs

@@ -414,31 +414,23 @@ namespace System.Reactive.Concurrency
         /// This type is very similar to ScheduledItem, but we need a different Invoke signature to allow customization
         /// of the target scheduler (e.g. when called in a recursive scheduling context, see ExecuteNextShortTermWorkItem).
         /// </remarks>
-        abstract class WorkItem : IComparable<WorkItem>, IDisposable
+        private abstract class WorkItem : IComparable<WorkItem>, IDisposable
         {
-            private readonly LocalScheduler _scheduler;
-            private readonly DateTimeOffset _dueTime;
+            public readonly LocalScheduler Scheduler;
+            public readonly DateTimeOffset DueTime;
+
             private readonly SingleAssignmentDisposable _disposable;
             private int _hasRun;
 
             public WorkItem(LocalScheduler scheduler, DateTimeOffset dueTime)
             {
-                _scheduler = scheduler;
-                _dueTime = dueTime;
+                Scheduler = scheduler;
+                DueTime = dueTime;
+
                 _disposable = new SingleAssignmentDisposable();
                 _hasRun = 0;
             }
 
-            public LocalScheduler Scheduler
-            {
-                get { return _scheduler; }
-            }
-
-            public DateTimeOffset DueTime
-            {
-                get { return _dueTime; }
-            }
-
             public void Invoke(IScheduler scheduler)
             {
                 //
@@ -452,33 +444,29 @@ namespace System.Reactive.Concurrency
                     try
                     {
                         if (!_disposable.IsDisposed)
+                        {
                             _disposable.Disposable = InvokeCore(scheduler);
+                        }
                     }
                     finally
                     {
                         SystemClock.Release();
                     }
-                }                
+                }
             }
 
             protected abstract IDisposable InvokeCore(IScheduler scheduler);
 
-            public int CompareTo(WorkItem/*!*/ other)
-            {
-                return Comparer<DateTimeOffset>.Default.Compare(this._dueTime, other._dueTime);
-            }
+            public int CompareTo(WorkItem/*!*/ other) => Comparer<DateTimeOffset>.Default.Compare(DueTime, other.DueTime);
 
-            public void Dispose()
-            {
-                _disposable.Dispose();
-            }
+            public void Dispose() => _disposable.Dispose();
         }
 
         /// <summary>
         /// Represents a work item that closes over scheduler invocation state. Subtyping is
         /// used to have a common type for the scheduler queues.
         /// </summary>
-        sealed class WorkItem<TState> : WorkItem
+        private sealed class WorkItem<TState> : WorkItem
         {
             private readonly TState _state;
             private readonly Func<IScheduler, TState, IDisposable> _action;
@@ -490,10 +478,7 @@ namespace System.Reactive.Concurrency
                 _action = action;
             }
 
-            protected override IDisposable InvokeCore(IScheduler scheduler)
-            {
-                return _action(scheduler, _state);
-            }
+            protected override IDisposable InvokeCore(IScheduler scheduler) => _action(scheduler, _state);
         }
     }
-}
+}

+ 8 - 17
Rx.NET/Source/src/System.Reactive/Concurrency/LocalScheduler.cs

@@ -12,10 +12,7 @@ namespace System.Reactive.Concurrency
         /// <summary>
         /// Gets the scheduler's notion of current time.
         /// </summary>
-        public virtual DateTimeOffset Now
-        {
-            get { return Scheduler.Now; }
-        }
+        public virtual DateTimeOffset Now => Scheduler.Now;
 
         /// <summary>
         /// Schedules an action to be executed.
@@ -24,7 +21,7 @@ namespace System.Reactive.Concurrency
         /// <param name="state">State passed to the action to be executed.</param>
         /// <param name="action">Action to be executed.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
         public virtual IDisposable Schedule<TState>(TState state, Func<IScheduler, TState, IDisposable> action)
         {
             if (action == null)
@@ -51,7 +48,7 @@ namespace System.Reactive.Concurrency
         /// <param name="action">Action to be executed.</param>
         /// <param name="dueTime">Absolute time at which to execute the action.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
         public virtual IDisposable Schedule<TState>(TState state, DateTimeOffset dueTime, Func<IScheduler, TState, IDisposable> action)
         {
             if (action == null)
@@ -65,18 +62,12 @@ namespace System.Reactive.Concurrency
         /// </summary>
         /// <returns>New stopwatch object; started at the time of the request.</returns>
         /// <remarks>
-        /// Platform-specific scheduler implementations should reimplement IStopwatchProvider to provide a more
-        /// efficient IStopwatch implementation (if available).
+        /// Platform-specific scheduler implementations should reimplement <see cref="IStopwatchProvider"/>
+        /// to provide a more efficient <see cref="IStopwatch"/> implementation (if available).
         /// </remarks>
-        public virtual IStopwatch StartStopwatch()
-        {
-            return ConcurrencyAbstractionLayer.Current.StartStopwatch();
-        }
+        public virtual IStopwatch StartStopwatch() => ConcurrencyAbstractionLayer.Current.StartStopwatch();
 
-        object IServiceProvider.GetService(Type serviceType)
-        {
-            return GetService(serviceType);
-        }
+        object IServiceProvider.GetService(Type serviceType) => GetService(serviceType);
 
         /// <summary>
         /// Discovers scheduler services by interface type. The base class implementation returns
@@ -84,7 +75,7 @@ namespace System.Reactive.Concurrency
         /// more control over service discovery, derived types can override this method.
         /// </summary>
         /// <param name="serviceType">Scheduler service interface type to discover.</param>
-        /// <returns>Object implementing the requested service, if available; null otherwise.</returns>
+        /// <returns>Object implementing the requested service, if available; <c>null</c> otherwise.</returns>
         protected virtual object GetService(Type serviceType)
         {
 #if !NO_PERF

+ 7 - 13
Rx.NET/Source/src/System.Reactive/Concurrency/NewThreadScheduler.cs

@@ -27,20 +27,14 @@ namespace System.Reactive.Concurrency
         /// <summary>
         /// Gets an instance of this scheduler that uses the default Thread constructor.
         /// </summary>
-        public static NewThreadScheduler Default
-        {
-            get
-            {
-                return s_instance.Value;
-            }
-        }
+        public static NewThreadScheduler Default => s_instance.Value;
 
 #if !NO_THREAD
         /// <summary>
         /// Creates an object that schedules each unit of work on a separate thread.
         /// </summary>
         /// <param name="threadFactory">Factory function for thread creation.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="threadFactory"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="threadFactory"/> is <c>null</c>.</exception>
         public NewThreadScheduler(Func<ThreadStart, Thread> threadFactory)
         {
             if (threadFactory == null)
@@ -60,7 +54,7 @@ namespace System.Reactive.Concurrency
         /// <param name="action">Action to be executed.</param>
         /// <param name="dueTime">Relative time after which to execute the action.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
         public override IDisposable Schedule<TState>(TState state, TimeSpan dueTime, Func<IScheduler, TState, IDisposable> action)
         {
             if (action == null)
@@ -78,7 +72,7 @@ namespace System.Reactive.Concurrency
         /// <param name="state">State passed to the action to be executed.</param>
         /// <param name="action">Action to be executed.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
         public IDisposable ScheduleLongRunning<TState>(TState state, Action<TState, ICancelable> action)
         {
             if (action == null)
@@ -109,8 +103,8 @@ namespace System.Reactive.Concurrency
         /// <param name="period">Period for running the work periodically.</param>
         /// <param name="action">Action to be executed, potentially updating the state.</param>
         /// <returns>The disposable object used to cancel the scheduled recurring action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="period"/> is less than TimeSpan.Zero.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="period"/> is less than <see cref="TimeSpan.Zero"/>.</exception>
         public IDisposable SchedulePeriodic<TState>(TState state, TimeSpan period, Func<TState, TState> action)
         {
             if (period < TimeSpan.Zero)
@@ -126,7 +120,7 @@ namespace System.Reactive.Concurrency
             return periodic;
         }
 
-        class Periodic<TState> : IDisposable
+        private sealed class Periodic<TState> : IDisposable
         {
             private readonly IStopwatch _stopwatch;
             private readonly TimeSpan _period;

+ 32 - 58
Rx.NET/Source/src/System.Reactive/Concurrency/ScheduledItem.cs

@@ -22,7 +22,7 @@ namespace System.Reactive.Concurrency
         /// </summary>
         /// <param name="dueTime">Absolute time at which the work item has to be executed.</param>
         /// <param name="comparer">Comparer used to compare work items based on their scheduled time.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="comparer"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="comparer"/> is <c>null</c>.</exception>
         protected ScheduledItem(TAbsolute dueTime, IComparer<TAbsolute> comparer)
         {
             if (comparer == null)
@@ -43,7 +43,9 @@ namespace System.Reactive.Concurrency
         public void Invoke()
         {
             if (!_disposable.IsDisposed)
+            {
                 _disposable.Disposable = InvokeCore();
+            }
         }
 
         /// <summary>
@@ -59,12 +61,14 @@ namespace System.Reactive.Concurrency
         /// </summary>
         /// <param name="other">Work item to compare the current work item to.</param>
         /// <returns>Relative ordering between this and the specified work item.</returns>
-        /// <remarks>The inequality operators are overloaded to provide results consistent with the IComparable implementation. Equality operators implement traditional reference equality semantics.</remarks>
+        /// <remarks>The inequality operators are overloaded to provide results consistent with the <see cref="IComparable"/> implementation. Equality operators implement traditional reference equality semantics.</remarks>
         public int CompareTo(ScheduledItem<TAbsolute> other)
         {
-            // MSDN: By definition, any object compares greater than null, and two null references compare equal to each other. 
-            if (object.ReferenceEquals(other, null))
+            // MSDN: By definition, any object compares greater than null, and two null references compare equal to each other.
+            if (ReferenceEquals(other, null))
+            {
                 return 1;
+            }
 
             return _comparer.Compare(DueTime, other.DueTime);
         }
@@ -74,48 +78,36 @@ namespace System.Reactive.Concurrency
         /// </summary>
         /// <param name="left">The first object to compare.</param>
         /// <param name="right">The second object to compare.</param>
-        /// <returns>true if the DueTime value of left is earlier than the DueTime value of right; otherwise, false.</returns>
-        /// <remarks>This operator provides results consistent with the IComparable implementation.</remarks>
-        public static bool operator <(ScheduledItem<TAbsolute> left, ScheduledItem<TAbsolute> right)
-        {
-            return Comparer<ScheduledItem<TAbsolute>>.Default.Compare(left, right) < 0;
-        }
+        /// <returns><c>true</c> if the <see cref="DueTime"/> value of left is earlier than the <see cref="DueTime"/> value of right; otherwise, <c>false</c>.</returns>
+        /// <remarks>This operator provides results consistent with the <see cref="IComparable"/> implementation.</remarks>
+        public static bool operator <(ScheduledItem<TAbsolute> left, ScheduledItem<TAbsolute> right) => Comparer<ScheduledItem<TAbsolute>>.Default.Compare(left, right) < 0;
 
         /// <summary>
         /// Determines whether one specified <see cref="ScheduledItem{TAbsolute}" /> object is due before or at the same of a second specified <see cref="ScheduledItem{TAbsolute}" /> object.
         /// </summary>
         /// <param name="left">The first object to compare.</param>
         /// <param name="right">The second object to compare.</param>
-        /// <returns>true if the DueTime value of left is earlier than or simultaneous with the DueTime value of right; otherwise, false.</returns>
-        /// <remarks>This operator provides results consistent with the IComparable implementation.</remarks>
-        public static bool operator <=(ScheduledItem<TAbsolute> left, ScheduledItem<TAbsolute> right)
-        {
-            return Comparer<ScheduledItem<TAbsolute>>.Default.Compare(left, right) <= 0;
-        }
+        /// <returns><c>true</c> if the <see cref="DueTime"/> value of left is earlier than or simultaneous with the <see cref="DueTime"/> value of right; otherwise, <c>false</c>.</returns>
+        /// <remarks>This operator provides results consistent with the <see cref="IComparable"/> implementation.</remarks>
+        public static bool operator <=(ScheduledItem<TAbsolute> left, ScheduledItem<TAbsolute> right) => Comparer<ScheduledItem<TAbsolute>>.Default.Compare(left, right) <= 0;
 
         /// <summary>
         /// Determines whether one specified <see cref="ScheduledItem{TAbsolute}" /> object is due after a second specified <see cref="ScheduledItem{TAbsolute}" /> object.
         /// </summary>
         /// <param name="left">The first object to compare.</param>
         /// <param name="right">The second object to compare.</param>
-        /// <returns>true if the DueTime value of left is later than the DueTime value of right; otherwise, false.</returns>
-        /// <remarks>This operator provides results consistent with the IComparable implementation.</remarks>
-        public static bool operator >(ScheduledItem<TAbsolute> left, ScheduledItem<TAbsolute> right)
-        {
-            return Comparer<ScheduledItem<TAbsolute>>.Default.Compare(left, right) > 0;
-        }
+        /// <returns><c>true</c> if the <see cref="DueTime"/> value of left is later than the <see cref="DueTime"/> value of right; otherwise, <c>false</c>.</returns>
+        /// <remarks>This operator provides results consistent with the <see cref="IComparable"/> implementation.</remarks>
+        public static bool operator >(ScheduledItem<TAbsolute> left, ScheduledItem<TAbsolute> right) => Comparer<ScheduledItem<TAbsolute>>.Default.Compare(left, right) > 0;
 
         /// <summary>
         /// Determines whether one specified <see cref="ScheduledItem{TAbsolute}" /> object is due after or at the same time of a second specified <see cref="ScheduledItem{TAbsolute}" /> object.
         /// </summary>
         /// <param name="left">The first object to compare.</param>
         /// <param name="right">The second object to compare.</param>
-        /// <returns>true if the DueTime value of left is later than or simultaneous with the DueTime value of right; otherwise, false.</returns>
-        /// <remarks>This operator provides results consistent with the IComparable implementation.</remarks>
-        public static bool operator >=(ScheduledItem<TAbsolute> left, ScheduledItem<TAbsolute> right)
-        {
-            return Comparer<ScheduledItem<TAbsolute>>.Default.Compare(left, right) >= 0;
-        }
+        /// <returns><c>true</c> if the <see cref="DueTime"/> value of left is later than or simultaneous with the <see cref="DueTime"/> value of right; otherwise, <c>false</c>.</returns>
+        /// <remarks>This operator provides results consistent with the <see cref="IComparable"/> implementation.</remarks>
+        public static bool operator >=(ScheduledItem<TAbsolute> left, ScheduledItem<TAbsolute> right) => Comparer<ScheduledItem<TAbsolute>>.Default.Compare(left, right) >= 0;
 
         #endregion
 
@@ -126,53 +118,38 @@ namespace System.Reactive.Concurrency
         /// </summary>
         /// <param name="left">The first object to compare.</param>
         /// <param name="right">The second object to compare.</param>
-        /// <returns>true if both <see cref="ScheduledItem{TAbsolute, TValue}" /> are equal; otherwise, false.</returns>
+        /// <returns><c>true</c> if both <see cref="ScheduledItem{TAbsolute, TValue}" /> are equal; otherwise, <c>false</c>.</returns>
         /// <remarks>This operator does not provide results consistent with the IComparable implementation. Instead, it implements reference equality.</remarks>
-        public static bool operator ==(ScheduledItem<TAbsolute> left, ScheduledItem<TAbsolute> right)
-        {
-            return object.ReferenceEquals(left, right);
-        }
+        public static bool operator ==(ScheduledItem<TAbsolute> left, ScheduledItem<TAbsolute> right) => ReferenceEquals(left, right);
 
         /// <summary>
         /// Determines whether two specified <see cref="ScheduledItem{TAbsolute, TValue}" /> objects are inequal.
         /// </summary>
         /// <param name="left">The first object to compare.</param>
         /// <param name="right">The second object to compare.</param>
-        /// <returns>true if both <see cref="ScheduledItem{TAbsolute, TValue}" /> are inequal; otherwise, false.</returns>
+        /// <returns><c>true</c> if both <see cref="ScheduledItem{TAbsolute, TValue}" /> are inequal; otherwise, <c>false</c>.</returns>
         /// <remarks>This operator does not provide results consistent with the IComparable implementation. Instead, it implements reference equality.</remarks>
-        public static bool operator !=(ScheduledItem<TAbsolute> left, ScheduledItem<TAbsolute> right)
-        {
-            return !(left == right);
-        }
+        public static bool operator !=(ScheduledItem<TAbsolute> left, ScheduledItem<TAbsolute> right) => !(left == right);
 
         /// <summary>
         /// Determines whether a <see cref="ScheduledItem{TAbsolute}" /> object is equal to the specified object.
         /// </summary>
         /// <param name="obj">The object to compare to the current <see cref="ScheduledItem{TAbsolute}" /> object.</param>
-        /// <returns>true if the obj parameter is a <see cref="ScheduledItem{TAbsolute}" /> object and is equal to the current <see cref="ScheduledItem{TAbsolute}" /> object; otherwise, false.</returns>
-        public override bool Equals(object obj)
-        {
-            return object.ReferenceEquals(this, obj);
-        }
+        /// <returns><c>true</c> if the obj parameter is a <see cref="ScheduledItem{TAbsolute}" /> object and is equal to the current <see cref="ScheduledItem{TAbsolute}" /> object; otherwise, <c>false</c>.</returns>
+        public override bool Equals(object obj) => ReferenceEquals(this, obj);
 
         /// <summary>
         /// Returns the hash code for the current <see cref="ScheduledItem{TAbsolute}" /> object.
         /// </summary>
         /// <returns>A 32-bit signed integer hash code.</returns>
-        public override int GetHashCode()
-        {
-            return base.GetHashCode();
-        }
+        public override int GetHashCode() => base.GetHashCode();
 
         #endregion
 
         /// <summary>
-        /// Cancels the work item by disposing the resource returned by InvokeCore as soon as possible.
+        /// Cancels the work item by disposing the resource returned by <see cref="InvokeCore"/> as soon as possible.
         /// </summary>
-        public void Cancel()
-        {
-            _disposable.Dispose();
-        }
+        public void Cancel() => _disposable.Dispose();
 
         /// <summary>
         /// Gets whether the work item has received a cancellation request.
@@ -200,7 +177,7 @@ namespace System.Reactive.Concurrency
         /// <param name="action">Scheduled action.</param>
         /// <param name="dueTime">Time at which to run the scheduled action.</param>
         /// <param name="comparer">Comparer used to compare work items based on their scheduled time.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> or <paramref name="comparer"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> or <paramref name="comparer"/> is <c>null</c>.</exception>
         public ScheduledItem(IScheduler scheduler, TValue state, Func<IScheduler, TValue, IDisposable> action, TAbsolute dueTime, IComparer<TAbsolute> comparer)
             : base(dueTime, comparer)
         {
@@ -221,7 +198,7 @@ namespace System.Reactive.Concurrency
         /// <param name="state">State to pass to the scheduled action.</param>
         /// <param name="action">Scheduled action.</param>
         /// <param name="dueTime">Time at which to run the scheduled action.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is <c>null</c>.</exception>
         public ScheduledItem(IScheduler scheduler, TValue state, Func<IScheduler, TValue, IDisposable> action, TAbsolute dueTime)
             : this(scheduler, state, action, dueTime, Comparer<TAbsolute>.Default)
         {
@@ -231,9 +208,6 @@ namespace System.Reactive.Concurrency
         /// Invokes the scheduled action with the supplied recursive scheduler and state.
         /// </summary>
         /// <returns>Cancellation resource returned by the scheduled action.</returns>
-        protected override IDisposable InvokeCore()
-        {
-            return _action(_scheduler, _state);
-        }
+        protected override IDisposable InvokeCore() => _action(_scheduler, _state);
     }
 }

+ 23 - 25
Rx.NET/Source/src/System.Reactive/Concurrency/Scheduler.Async.cs

@@ -16,7 +16,7 @@ namespace System.Reactive.Concurrency
         /// </summary>
         /// <param name="scheduler">Scheduler to yield work on.</param>
         /// <returns>Scheduler operation object to await in order to schedule the continuation.</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is <c>null</c>.</exception>
         public static SchedulerOperation Yield(this IScheduler scheduler)
         {
             if (scheduler == null)
@@ -32,7 +32,7 @@ namespace System.Reactive.Concurrency
         /// <param name="scheduler">Scheduler to yield work on.</param>
         /// <param name="cancellationToken">Cancellation token to cancel the continuation to run.</param>
         /// <returns>Scheduler operation object to await in order to schedule the continuation.</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is <c>null</c>.</exception>
         public static SchedulerOperation Yield(this IScheduler scheduler, CancellationToken cancellationToken)
         {
             if (scheduler == null)
@@ -48,7 +48,7 @@ namespace System.Reactive.Concurrency
         /// <param name="scheduler">Scheduler to yield work on.</param>
         /// <param name="dueTime">Time when the continuation should run.</param>
         /// <returns>Scheduler operation object to await in order to schedule the continuation.</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is <c>null</c>.</exception>
         public static SchedulerOperation Sleep(this IScheduler scheduler, TimeSpan dueTime)
         {
             if (scheduler == null)
@@ -65,7 +65,7 @@ namespace System.Reactive.Concurrency
         /// <param name="dueTime">Time when the continuation should run.</param>
         /// <param name="cancellationToken">Cancellation token to cancel the continuation to run.</param>
         /// <returns>Scheduler operation object to await in order to schedule the continuation.</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is <c>null</c>.</exception>
         public static SchedulerOperation Sleep(this IScheduler scheduler, TimeSpan dueTime, CancellationToken cancellationToken)
         {
             if (scheduler == null)
@@ -81,7 +81,7 @@ namespace System.Reactive.Concurrency
         /// <param name="scheduler">Scheduler to yield work on.</param>
         /// <param name="dueTime">Time when the continuation should run.</param>
         /// <returns>Scheduler operation object to await in order to schedule the continuation.</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is <c>null</c>.</exception>
         public static SchedulerOperation Sleep(this IScheduler scheduler, DateTimeOffset dueTime)
         {
             if (scheduler == null)
@@ -98,7 +98,7 @@ namespace System.Reactive.Concurrency
         /// <param name="dueTime">Time when the continuation should run.</param>
         /// <param name="cancellationToken">Cancellation token to cancel the continuation to run.</param>
         /// <returns>Scheduler operation object to await in order to schedule the continuation.</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is <c>null</c>.</exception>
         public static SchedulerOperation Sleep(this IScheduler scheduler, DateTimeOffset dueTime, CancellationToken cancellationToken)
         {
             if (scheduler == null)
@@ -115,7 +115,7 @@ namespace System.Reactive.Concurrency
         /// <param name="state">State to pass to the asynchronous method.</param>
         /// <param name="action">Asynchronous method to run the work, using Yield and Sleep operations for cooperative scheduling and injection of cancellation points.</param>
         /// <returns>Disposable object that allows to cancel outstanding work on cooperative cancellation points or through the cancellation token passed to the asynchronous method.</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is <c>null</c>.</exception>
         public static IDisposable ScheduleAsync<TState>(this IScheduler scheduler, TState state, Func<IScheduler, TState, CancellationToken, Task> action)
         {
             if (scheduler == null)
@@ -134,7 +134,7 @@ namespace System.Reactive.Concurrency
         /// <param name="state">State to pass to the asynchronous method.</param>
         /// <param name="action">Asynchronous method to run the work, using Yield and Sleep operations for cooperative scheduling and injection of cancellation points.</param>
         /// <returns>Disposable object that allows to cancel outstanding work on cooperative cancellation points or through the cancellation token passed to the asynchronous method.</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is <c>null</c>.</exception>
         public static IDisposable ScheduleAsync<TState>(this IScheduler scheduler, TState state, Func<IScheduler, TState, CancellationToken, Task<IDisposable>> action)
         {
             if (scheduler == null)
@@ -151,7 +151,7 @@ namespace System.Reactive.Concurrency
         /// <param name="scheduler">Scheduler to schedule work on.</param>
         /// <param name="action">Asynchronous method to run the work, using Yield and Sleep operations for cooperative scheduling and injection of cancellation points.</param>
         /// <returns>Disposable object that allows to cancel outstanding work on cooperative cancellation points or through the cancellation token passed to the asynchronous method.</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is <c>null</c>.</exception>
         public static IDisposable ScheduleAsync(this IScheduler scheduler, Func<IScheduler, CancellationToken, Task> action)
         {
             if (scheduler == null)
@@ -168,7 +168,7 @@ namespace System.Reactive.Concurrency
         /// <param name="scheduler">Scheduler to schedule work on.</param>
         /// <param name="action">Asynchronous method to run the work, using Yield and Sleep operations for cooperative scheduling and injection of cancellation points.</param>
         /// <returns>Disposable object that allows to cancel outstanding work on cooperative cancellation points or through the cancellation token passed to the asynchronous method.</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is <c>null</c>.</exception>
         public static IDisposable ScheduleAsync(this IScheduler scheduler, Func<IScheduler, CancellationToken, Task<IDisposable>> action)
         {
             if (scheduler == null)
@@ -188,7 +188,7 @@ namespace System.Reactive.Concurrency
         /// <param name="dueTime">Relative time after which to execute the action.</param>
         /// <param name="action">Asynchronous method to run the work, using Yield and Sleep operations for cooperative scheduling and injection of cancellation points.</param>
         /// <returns>Disposable object that allows to cancel outstanding work on cooperative cancellation points or through the cancellation token passed to the asynchronous method.</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is <c>null</c>.</exception>
         public static IDisposable ScheduleAsync<TState>(this IScheduler scheduler, TState state, TimeSpan dueTime, Func<IScheduler, TState, CancellationToken, Task> action)
         {
             if (scheduler == null)
@@ -208,7 +208,7 @@ namespace System.Reactive.Concurrency
         /// <param name="dueTime">Relative time after which to execute the action.</param>
         /// <param name="action">Asynchronous method to run the work, using Yield and Sleep operations for cooperative scheduling and injection of cancellation points.</param>
         /// <returns>Disposable object that allows to cancel outstanding work on cooperative cancellation points or through the cancellation token passed to the asynchronous method.</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is <c>null</c>.</exception>
         public static IDisposable ScheduleAsync<TState>(this IScheduler scheduler, TState state, TimeSpan dueTime, Func<IScheduler, TState, CancellationToken, Task<IDisposable>> action)
         {
             if (scheduler == null)
@@ -226,7 +226,7 @@ namespace System.Reactive.Concurrency
         /// <param name="dueTime">Relative time after which to execute the action.</param>
         /// <param name="action">Asynchronous method to run the work, using Yield and Sleep operations for cooperative scheduling and injection of cancellation points.</param>
         /// <returns>Disposable object that allows to cancel outstanding work on cooperative cancellation points or through the cancellation token passed to the asynchronous method.</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is <c>null</c>.</exception>
         public static IDisposable ScheduleAsync(this IScheduler scheduler, TimeSpan dueTime, Func<IScheduler, CancellationToken, Task> action)
         {
             if (scheduler == null)
@@ -244,7 +244,7 @@ namespace System.Reactive.Concurrency
         /// <param name="dueTime">Relative time after which to execute the action.</param>
         /// <param name="action">Asynchronous method to run the work, using Yield and Sleep operations for cooperative scheduling and injection of cancellation points.</param>
         /// <returns>Disposable object that allows to cancel outstanding work on cooperative cancellation points or through the cancellation token passed to the asynchronous method.</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is <c>null</c>.</exception>
         public static IDisposable ScheduleAsync(this IScheduler scheduler, TimeSpan dueTime, Func<IScheduler, CancellationToken, Task<IDisposable>> action)
         {
             if (scheduler == null)
@@ -264,7 +264,7 @@ namespace System.Reactive.Concurrency
         /// <param name="dueTime">Absolute time at which to execute the action.</param>
         /// <param name="action">Asynchronous method to run the work, using Yield and Sleep operations for cooperative scheduling and injection of cancellation points.</param>
         /// <returns>Disposable object that allows to cancel outstanding work on cooperative cancellation points or through the cancellation token passed to the asynchronous method.</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is <c>null</c>.</exception>
         public static IDisposable ScheduleAsync<TState>(this IScheduler scheduler, TState state, DateTimeOffset dueTime, Func<IScheduler, TState, CancellationToken, Task> action)
         {
             if (scheduler == null)
@@ -284,7 +284,7 @@ namespace System.Reactive.Concurrency
         /// <param name="dueTime">Absolute time at which to execute the action.</param>
         /// <param name="action">Asynchronous method to run the work, using Yield and Sleep operations for cooperative scheduling and injection of cancellation points.</param>
         /// <returns>Disposable object that allows to cancel outstanding work on cooperative cancellation points or through the cancellation token passed to the asynchronous method.</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is <c>null</c>.</exception>
         public static IDisposable ScheduleAsync<TState>(this IScheduler scheduler, TState state, DateTimeOffset dueTime, Func<IScheduler, TState, CancellationToken, Task<IDisposable>> action)
         {
             if (scheduler == null)
@@ -302,7 +302,7 @@ namespace System.Reactive.Concurrency
         /// <param name="dueTime">Absolute time at which to execute the action.</param>
         /// <param name="action">Asynchronous method to run the work, using Yield and Sleep operations for cooperative scheduling and injection of cancellation points.</param>
         /// <returns>Disposable object that allows to cancel outstanding work on cooperative cancellation points or through the cancellation token passed to the asynchronous method.</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is <c>null</c>.</exception>
         public static IDisposable ScheduleAsync(this IScheduler scheduler, DateTimeOffset dueTime, Func<IScheduler, CancellationToken, Task> action)
         {
             if (scheduler == null)
@@ -320,7 +320,7 @@ namespace System.Reactive.Concurrency
         /// <param name="dueTime">Absolute time at which to execute the action.</param>
         /// <param name="action">Asynchronous method to run the work, using Yield and Sleep operations for cooperative scheduling and injection of cancellation points.</param>
         /// <returns>Disposable object that allows to cancel outstanding work on cooperative cancellation points or through the cancellation token passed to the asynchronous method.</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is <c>null</c>.</exception>
         public static IDisposable ScheduleAsync(this IScheduler scheduler, DateTimeOffset dueTime, Func<IScheduler, CancellationToken, Task<IDisposable>> action)
         {
             if (scheduler == null)
@@ -372,7 +372,9 @@ namespace System.Reactive.Concurrency
                     return;
 
                 if (t.Exception != null)
+                {
                     t.Exception.Handle(e => e is OperationCanceledException);
+                }
 
                 d.Disposable = t.Result;
             }, TaskContinuationOptions.ExecuteSynchronously);
@@ -391,7 +393,7 @@ namespace System.Reactive.Concurrency
             return cs != null ? cs.Token : CancellationToken.None;
         }
 
-        class CancelableScheduler : IScheduler
+        private sealed class CancelableScheduler : IScheduler
         {
             private readonly IScheduler _scheduler;
             private readonly CancellationToken _cancellationToken;
@@ -407,10 +409,7 @@ namespace System.Reactive.Concurrency
                 get { return _cancellationToken; }
             }
 
-            public DateTimeOffset Now
-            {
-                get { return _scheduler.Now; }
-            }
+            public DateTimeOffset Now => _scheduler.Now;
 
             public IDisposable Schedule<TState>(TState state, Func<IScheduler, TState, IDisposable> action)
             {
@@ -427,6 +426,5 @@ namespace System.Reactive.Concurrency
                 return _scheduler.Schedule(state, dueTime, action);
             }
         }
-
     }
-}
+}

+ 22 - 10
Rx.NET/Source/src/System.Reactive/Concurrency/Scheduler.Recursive.cs

@@ -14,7 +14,7 @@ namespace System.Reactive.Concurrency
         /// <param name="scheduler">Scheduler to execute the recursive action on.</param>
         /// <param name="action">Action to execute recursively. The parameter passed to the action is used to trigger recursive scheduling of the action.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is <c>null</c>.</exception>
         public static IDisposable Schedule(this IScheduler scheduler, Action<Action> action)
         {
             if (scheduler == null)
@@ -33,7 +33,7 @@ namespace System.Reactive.Concurrency
         /// <param name="state">State passed to the action to be executed.</param>
         /// <param name="action">Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in recursive invocation state.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is <c>null</c>.</exception>
         public static IDisposable Schedule<TState>(this IScheduler scheduler, TState state, Action<TState, Action<TState>> action)
         {
             if (scheduler == null)
@@ -44,7 +44,7 @@ namespace System.Reactive.Concurrency
             return scheduler.Schedule(new Pair<TState, Action<TState, Action<TState>>> { First = state, Second = action }, InvokeRec1);
         }
 
-        static IDisposable InvokeRec1<TState>(IScheduler scheduler, Pair<TState, Action<TState, Action<TState>>> pair)
+        private static IDisposable InvokeRec1<TState>(IScheduler scheduler, Pair<TState, Action<TState, Action<TState>>> pair)
         {
             var group = new CompositeDisposable(1);
             var gate = new object();
@@ -62,9 +62,13 @@ namespace System.Reactive.Concurrency
                     lock (gate)
                     {
                         if (isAdded)
+                        {
                             group.Remove(d);
+                        }
                         else
+                        {
                             isDone = true;
+                        }
                     }
                     recursiveAction(state3);
                     return Disposable.Empty;
@@ -92,7 +96,7 @@ namespace System.Reactive.Concurrency
         /// <param name="action">Action to execute recursively. The parameter passed to the action is used to trigger recursive scheduling of the action at the specified relative time.</param>
         /// <param name="dueTime">Relative time after which to execute the action for the first time.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is <c>null</c>.</exception>
         public static IDisposable Schedule(this IScheduler scheduler, TimeSpan dueTime, Action<Action<TimeSpan>> action)
         {
             if (scheduler == null)
@@ -112,7 +116,7 @@ namespace System.Reactive.Concurrency
         /// <param name="action">Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in the recursive due time and invocation state.</param>
         /// <param name="dueTime">Relative time after which to execute the action for the first time.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is <c>null</c>.</exception>
         public static IDisposable Schedule<TState>(this IScheduler scheduler, TState state, TimeSpan dueTime, Action<TState, Action<TState, TimeSpan>> action)
         {
             if (scheduler == null)
@@ -123,7 +127,7 @@ namespace System.Reactive.Concurrency
             return scheduler.Schedule(new Pair<TState, Action<TState, Action<TState, TimeSpan>>> { First = state, Second = action }, dueTime, InvokeRec2);
         }
 
-        static IDisposable InvokeRec2<TState>(IScheduler scheduler, Pair<TState, Action<TState, Action<TState, TimeSpan>>> pair)
+        private static IDisposable InvokeRec2<TState>(IScheduler scheduler, Pair<TState, Action<TState, Action<TState, TimeSpan>>> pair)
         {
             var group = new CompositeDisposable(1);
             var gate = new object();
@@ -141,9 +145,13 @@ namespace System.Reactive.Concurrency
                     lock (gate)
                     {
                         if (isAdded)
+                        {
                             group.Remove(d);
+                        }
                         else
+                        {
                             isDone = true;
+                        }
                     }
                     recursiveAction(state3);
                     return Disposable.Empty;
@@ -171,7 +179,7 @@ namespace System.Reactive.Concurrency
         /// <param name="action">Action to execute recursively. The parameter passed to the action is used to trigger recursive scheduling of the action at the specified absolute time.</param>
         /// <param name="dueTime">Absolute time at which to execute the action for the first time.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is <c>null</c>.</exception>
         public static IDisposable Schedule(this IScheduler scheduler, DateTimeOffset dueTime, Action<Action<DateTimeOffset>> action)
         {
             if (scheduler == null)
@@ -191,7 +199,7 @@ namespace System.Reactive.Concurrency
         /// <param name="action">Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in the recursive due time and invocation state.</param>
         /// <param name="dueTime">Absolute time at which to execute the action for the first time.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is <c>null</c>.</exception>
         public static IDisposable Schedule<TState>(this IScheduler scheduler, TState state, DateTimeOffset dueTime, Action<TState, Action<TState, DateTimeOffset>> action)
         {
             if (scheduler == null)
@@ -202,7 +210,7 @@ namespace System.Reactive.Concurrency
             return scheduler.Schedule(new Pair<TState, Action<TState, Action<TState, DateTimeOffset>>> { First = state, Second = action }, dueTime, InvokeRec3);
         }
 
-        static IDisposable InvokeRec3<TState>(IScheduler scheduler, Pair<TState, Action<TState, Action<TState, DateTimeOffset>>> pair)
+        private static IDisposable InvokeRec3<TState>(IScheduler scheduler, Pair<TState, Action<TState, Action<TState, DateTimeOffset>>> pair)
         {
             var group = new CompositeDisposable(1);
             var gate = new object();
@@ -220,9 +228,13 @@ namespace System.Reactive.Concurrency
                     lock (gate)
                     {
                         if (isAdded)
+                        {
                             group.Remove(d);
+                        }
                         else
+                        {
                             isDone = true;
+                        }
                     }
                     recursiveAction(state3);
                     return Disposable.Empty;
@@ -246,7 +258,7 @@ namespace System.Reactive.Concurrency
 #if !NO_SERIALIZABLE
         [Serializable]
 #endif
-        struct Pair<T1, T2>
+        private struct Pair<T1, T2>
         {
             public T1 First;
             public T2 Second;

+ 23 - 14
Rx.NET/Source/src/System.Reactive/Concurrency/Scheduler.Services.Emulation.cs

@@ -23,8 +23,8 @@ namespace System.Reactive.Concurrency
         /// <param name="period">Period for running the work periodically.</param>
         /// <param name="action">Action to be executed, potentially updating the state.</param>
         /// <returns>The disposable object used to cancel the scheduled recurring action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is null.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="period"/> is less than TimeSpan.Zero.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is <c>null</c>.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="period"/> is less than <see cref="TimeSpan.Zero"/>.</exception>
         public static IDisposable SchedulePeriodic<TState>(this IScheduler scheduler, TState state, TimeSpan period, Func<TState, TState> action)
         {
             if (scheduler == null)
@@ -49,8 +49,8 @@ namespace System.Reactive.Concurrency
         /// <param name="period">Period for running the work periodically.</param>
         /// <param name="action">Action to be executed.</param>
         /// <returns>The disposable object used to cancel the scheduled recurring action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is null.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="period"/> is less than TimeSpan.Zero.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is <c>null</c>.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="period"/> is less than <see cref="TimeSpan.Zero"/>.</exception>
         public static IDisposable SchedulePeriodic<TState>(this IScheduler scheduler, TState state, TimeSpan period, Action<TState> action)
         {
             if (scheduler == null)
@@ -73,8 +73,8 @@ namespace System.Reactive.Concurrency
         /// <param name="period">Period for running the work periodically.</param>
         /// <param name="action">Action to be executed.</param>
         /// <returns>The disposable object used to cancel the scheduled recurring action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is null.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="period"/> is less than TimeSpan.Zero.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is <c>null</c>.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="period"/> is less than <see cref="TimeSpan.Zero"/>.</exception>
         public static IDisposable SchedulePeriodic(this IScheduler scheduler, TimeSpan period, Action action)
         {
             if (scheduler == null)
@@ -94,7 +94,7 @@ namespace System.Reactive.Concurrency
         /// </summary>
         /// <param name="scheduler">Scheduler to obtain a stopwatch for.</param>
         /// <returns>New stopwatch object; started at the time of the request.</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is <c>null</c>.</exception>
         /// <remarks>The resulting stopwatch object can have non-monotonic behavior.</remarks>
         public static IStopwatch StartStopwatch(this IScheduler scheduler)
         {
@@ -135,7 +135,9 @@ namespace System.Reactive.Concurrency
             //
             var swp = scheduler.AsStopwatchProvider();
             if (swp != null)
+            {
                 return swp.StartStopwatch();
+            }
 
             return new EmulatedStopwatch(scheduler);
         }
@@ -287,7 +289,7 @@ namespace System.Reactive.Concurrency
             }
         }
 
-        class SchedulePeriodicStopwatch<TState>
+        private sealed class SchedulePeriodicStopwatch<TState>
         {
             private readonly IScheduler _scheduler;
             private readonly TimeSpan _period;
@@ -409,7 +411,9 @@ namespace System.Reactive.Concurrency
                     // once more.
                     //
                     if (shouldWaitForResume)
+                    {
                         _resumeEvent.WaitOne();
+                    }
                 }
 
                 recurse(next);
@@ -424,7 +428,9 @@ namespace System.Reactive.Concurrency
                     _runState = DISPOSED;
 
                     if (!Environment.HasShutdownStarted)
+                    {
                         _resumeEvent.Set();
+                    }
                 }
             }
 
@@ -452,7 +458,9 @@ namespace System.Reactive.Concurrency
                         _runState = SUSPENDED;
 
                         if (!Environment.HasShutdownStarted)
+                        {
                             _resumeEvent.Reset();
+                        }
                     }
                 }
             }
@@ -484,7 +492,9 @@ namespace System.Reactive.Concurrency
                         _runState = RUNNING;
 
                         if (!Environment.HasShutdownStarted)
+                        {
                             _resumeEvent.Set();
+                        }
                     }
                 }
             }
@@ -504,7 +514,7 @@ namespace System.Reactive.Concurrency
             }
         }
 
-        class SchedulePeriodicRecursive<TState>
+        private sealed class SchedulePeriodicRecursive<TState>
         {
             private readonly IScheduler _scheduler;
             private readonly TimeSpan _period;
@@ -605,14 +615,16 @@ namespace System.Reactive.Concurrency
                         // we make tail calls to play nice with the scheduler.
                         //
                         if (Interlocked.Decrement(ref _pendingTickCount) > 0)
+                        {
                             recurse(DISPATCH_START, TimeSpan.Zero);
+                        }
 
                         break;
                 }
             }
         }
 
-        class EmulatedStopwatch : IStopwatch
+        private sealed class EmulatedStopwatch : IStopwatch
         {
             private readonly IScheduler _scheduler;
             private readonly DateTimeOffset _start;
@@ -623,10 +635,7 @@ namespace System.Reactive.Concurrency
                 _start = _scheduler.Now;
             }
 
-            public TimeSpan Elapsed
-            {
-                get { return Scheduler.Normalize(_scheduler.Now - _start); }
-            }
+            public TimeSpan Elapsed => Normalize(_scheduler.Now - _start);
         }
     }
 }

+ 23 - 32
Rx.NET/Source/src/System.Reactive/Concurrency/Scheduler.Services.cs

@@ -18,70 +18,61 @@ namespace System.Reactive.Concurrency
         };
 
         /// <summary>
-        /// Returns the ISchedulerLongRunning implementation of the specified scheduler, or null if no such implementation is available.
+        /// Returns the <see cref="ISchedulerLongRunning"/> implementation of the specified scheduler, or <c>null</c> if no such implementation is available.
         /// </summary>
-        /// <param name="scheduler">Scheduler to get the ISchedulerLongRunning implementation for.</param>
-        /// <returns>The scheduler's ISchedulerLongRunning implementation if available; null otherwise.</returns>
+        /// <param name="scheduler">Scheduler to get the <see cref="ISchedulerLongRunning"/> implementation for.</param>
+        /// <returns>The scheduler's <see cref="ISchedulerLongRunning"/> implementation if available; <c>null</c> otherwise.</returns>
         /// <remarks>
         /// This helper method is made available for query operator authors in order to discover scheduler services by using the required
         /// IServiceProvider pattern, which allows for interception or redefinition of scheduler services.
         /// </remarks>
-        public static ISchedulerLongRunning AsLongRunning(this IScheduler scheduler)
-        {
-            var svc = scheduler as IServiceProvider;
-            if (svc != null)
-                return (ISchedulerLongRunning)svc.GetService(typeof(ISchedulerLongRunning));
-
-            return null;
-        }
+        public static ISchedulerLongRunning AsLongRunning(this IScheduler scheduler) => As<ISchedulerLongRunning>(scheduler);
 
         /// <summary>
-        /// Returns the IStopwatchProvider implementation of the specified scheduler, or null if no such implementation is available.
+        /// Returns the <see cref="IStopwatchProvider"/> implementation of the specified scheduler, or <c>null</c> if no such implementation is available.
         /// </summary>
-        /// <param name="scheduler">Scheduler to get the IStopwatchProvider implementation for.</param>
-        /// <returns>The scheduler's IStopwatchProvider implementation if available; null otherwise.</returns>
+        /// <param name="scheduler">Scheduler to get the <see cref="IStopwatchProvider"/> implementation for.</param>
+        /// <returns>The scheduler's <see cref="IStopwatchProvider"/> implementation if available; <c>null</c> otherwise.</returns>
         /// <remarks>
         /// <para>
         /// This helper method is made available for query operator authors in order to discover scheduler services by using the required
         /// IServiceProvider pattern, which allows for interception or redefinition of scheduler services.
         /// </para>
         /// <para>
-        /// Consider using <see cref="Scheduler.StartStopwatch"/> in case a stopwatch is required, but use of emulation stopwatch based
+        /// Consider using <see cref="StartStopwatch"/> in case a stopwatch is required, but use of emulation stopwatch based
         /// on the scheduler's clock is acceptable. Use of this method is recommended for best-effort use of the stopwatch provider
         /// scheduler service, where the caller falls back to not using stopwatches if this facility wasn't found.
         /// </para>
         /// </remarks>
-        public static IStopwatchProvider AsStopwatchProvider(this IScheduler scheduler)
-        {
-            var svc = scheduler as IServiceProvider;
-            if (svc != null)
-                return (IStopwatchProvider)svc.GetService(typeof(IStopwatchProvider));
-
-            return null;
-        }
+        public static IStopwatchProvider AsStopwatchProvider(this IScheduler scheduler) => As<IStopwatchProvider>(scheduler);
 
         /// <summary>
-        /// Returns the IStopwatchProvider implementation of the specified scheduler, or null if no such implementation is available.
+        /// Returns the <see cref="ISchedulerPeriodic"/> implementation of the specified scheduler, or <c>null</c> if no such implementation is available.
         /// </summary>
-        /// <param name="scheduler">Scheduler to get the IStopwatchProvider implementation for.</param>
-        /// <returns>The scheduler's IStopwatchProvider implementation if available; null otherwise.</returns>
+        /// <param name="scheduler">Scheduler to get the <see cref="ISchedulerPeriodic"/> implementation for.</param>
+        /// <returns>The scheduler's <see cref="ISchedulerPeriodic"/> implementation if available; <c>null</c> otherwise.</returns>
         /// <remarks>
         /// <para>
         /// This helper method is made available for query operator authors in order to discover scheduler services by using the required
         /// IServiceProvider pattern, which allows for interception or redefinition of scheduler services.
         /// </para>
         /// <para>
-        /// Consider using the Scheduler.SchedulePeriodic extension methods for IScheduler in case periodic scheduling is required and
-        /// emulation of periodic behavior using other scheduler services is desirable. Use of this method is recommended for best-effort
-        /// use of the periodic scheduling service, where the caller falls back to not using periodic scheduling if this facility wasn't
-        /// found.
+        /// Consider using the <see cref="SchedulePeriodic"/> extension methods for <see cref="IScheduler"/> in case periodic scheduling
+        /// is required and emulation of periodic behavior using other scheduler services is desirable. Use of this method is recommended
+        /// for best-effort use of the periodic scheduling service, where the caller falls back to not using periodic scheduling if this
+        /// facility wasn't found.
         /// </para>
         /// </remarks>
-        public static ISchedulerPeriodic AsPeriodic(this IScheduler scheduler)
+        public static ISchedulerPeriodic AsPeriodic(this IScheduler scheduler) => As<ISchedulerPeriodic>(scheduler);
+
+        private static T As<T>(IScheduler scheduler)
+            where T : class
         {
             var svc = scheduler as IServiceProvider;
             if (svc != null)
-                return (ISchedulerPeriodic)svc.GetService(typeof(ISchedulerPeriodic));
+            {
+                return (T)svc.GetService(typeof(T));
+            }
 
             return null;
         }

+ 5 - 5
Rx.NET/Source/src/System.Reactive/Concurrency/Scheduler.Simple.cs

@@ -14,7 +14,7 @@ namespace System.Reactive.Concurrency
         /// <param name="scheduler">Scheduler to execute the action on.</param>
         /// <param name="action">Action to execute.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is <c>null</c>.</exception>
         public static IDisposable Schedule(this IScheduler scheduler, Action action)
         {
             if (scheduler == null)
@@ -32,7 +32,7 @@ namespace System.Reactive.Concurrency
         /// <param name="action">Action to execute.</param>
         /// <param name="dueTime">Relative time after which to execute the action.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is <c>null</c>.</exception>
         public static IDisposable Schedule(this IScheduler scheduler, TimeSpan dueTime, Action action)
         {
             if (scheduler == null)
@@ -50,7 +50,7 @@ namespace System.Reactive.Concurrency
         /// <param name="action">Action to execute.</param>
         /// <param name="dueTime">Absolute time at which to execute the action.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is <c>null</c>.</exception>
         public static IDisposable Schedule(this IScheduler scheduler, DateTimeOffset dueTime, Action action)
         {
             if (scheduler == null)
@@ -67,7 +67,7 @@ namespace System.Reactive.Concurrency
         /// <param name="scheduler">Scheduler to execute the action on.</param>
         /// <param name="action">Action to execute.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is <c>null</c>.</exception>
         public static IDisposable ScheduleLongRunning(this ISchedulerLongRunning scheduler, Action<ICancelable> action)
         {
             if (scheduler == null)
@@ -78,7 +78,7 @@ namespace System.Reactive.Concurrency
             return scheduler.ScheduleLongRunning(action, (a, c) => a(c));
         }
 
-        static IDisposable Invoke(IScheduler scheduler, Action action)
+        private static IDisposable Invoke(IScheduler scheduler, Action action)
         {
             action();
             return Disposable.Empty;

+ 3 - 3
Rx.NET/Source/src/System.Reactive/Concurrency/Scheduler.Wrappers.cs

@@ -11,7 +11,7 @@ namespace System.Reactive.Concurrency
         /// </summary>
         /// <param name="scheduler">Scheduler to disable all optimizations for.</param>
         /// <returns>Proxy to the original scheduler but without any optimizations enabled.</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is <c>null</c>.</exception>
         public static IScheduler DisableOptimizations(this IScheduler scheduler)
         {
             if (scheduler == null)
@@ -26,7 +26,7 @@ namespace System.Reactive.Concurrency
         /// <param name="scheduler">Scheduler to disable the specified optimizations for.</param>
         /// <param name="optimizationInterfaces">Types of the optimization interfaces that have to be disabled.</param>
         /// <returns>Proxy to the original scheduler but without the specified optimizations enabled.</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="optimizationInterfaces"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="optimizationInterfaces"/> is <c>null</c>.</exception>
         public static IScheduler DisableOptimizations(this IScheduler scheduler, params Type[] optimizationInterfaces)
         {
             if (scheduler == null)
@@ -44,7 +44,7 @@ namespace System.Reactive.Concurrency
         /// <param name="scheduler">Scheduler to apply an exception filter for.</param>
         /// <param name="handler">Handler that's run if an exception is caught. The exception will be rethrown if the handler returns false.</param>
         /// <returns>Wrapper around the original scheduler, enforcing exception handling.</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="handler"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="handler"/> is <c>null</c>.</exception>
         public static IScheduler Catch<TException>(this IScheduler scheduler, Func<TException, bool> handler)
             where TException : Exception
         {

+ 11 - 58
Rx.NET/Source/src/System.Reactive/Concurrency/Scheduler.cs

@@ -21,58 +21,29 @@ namespace System.Reactive.Concurrency
         /// <summary>
         /// Gets the current time according to the local machine's system clock.
         /// </summary>
-        public static DateTimeOffset Now
-        {
-            get
-            {
-                return SystemClock.UtcNow;
-            }
-        }
+        public static DateTimeOffset Now => SystemClock.UtcNow;
 
         /// <summary>
-        /// Normalizes the specified TimeSpan value to a positive value.
+        /// Normalizes the specified <see cref="TimeSpan"/> value to a positive value.
         /// </summary>
-        /// <param name="timeSpan">The TimeSpan value to normalize.</param>
-        /// <returns>The specified TimeSpan value if it is zero or positive; otherwise, TimeSpan.Zero.</returns>
-        public static TimeSpan Normalize(TimeSpan timeSpan)
-        {
-            if (timeSpan.Ticks < 0)
-                return TimeSpan.Zero;
-            return timeSpan;
-        }
+        /// <param name="timeSpan">The <see cref="TimeSpan"/> value to normalize.</param>
+        /// <returns>The specified TimeSpan value if it is zero or positive; otherwise, <see cref="TimeSpan.Zero"/>.</returns>
+        public static TimeSpan Normalize(TimeSpan timeSpan) => timeSpan.Ticks < 0 ? TimeSpan.Zero : timeSpan;
 
         /// <summary>
         /// Gets a scheduler that schedules work immediately on the current thread.
         /// </summary>
-        public static ImmediateScheduler Immediate
-        {
-            get
-            {
-                return ImmediateScheduler.Instance;
-            }
-        }
+        public static ImmediateScheduler Immediate => ImmediateScheduler.Instance;
 
         /// <summary>
         /// Gets a scheduler that schedules work as soon as possible on the current thread.
         /// </summary>
-        public static CurrentThreadScheduler CurrentThread
-        {
-            get
-            {
-                return CurrentThreadScheduler.Instance;
-            }
-        }
+        public static CurrentThreadScheduler CurrentThread => CurrentThreadScheduler.Instance;
 
         /// <summary>
         /// Gets a scheduler that schedules work on the platform's default scheduler.
         /// </summary>
-        public static DefaultScheduler Default
-        {
-            get
-            {
-                return DefaultScheduler.Instance;
-            }
-        }
+        public static DefaultScheduler Default => DefaultScheduler.Instance;
 
 
         //
@@ -95,13 +66,7 @@ namespace System.Reactive.Concurrency
         /// Gets a scheduler that schedules work on the thread pool.
         /// </summary>
         [Obsolete(Constants_Core.OBSOLETE_SCHEDULER_THREADPOOL)]
-        public static IScheduler ThreadPool
-        {
-            get
-            {
-                return s_threadPool.Value;
-            }
-        }
+        public static IScheduler ThreadPool => s_threadPool.Value;
 
         private static Lazy<IScheduler> s_newThread = new Lazy<IScheduler>(() => Initialize("NewThread"));
 
@@ -109,13 +74,7 @@ namespace System.Reactive.Concurrency
         /// Gets a scheduler that schedules work on a new thread using default thread creation options.
         /// </summary>
         [Obsolete(Constants_Core.OBSOLETE_SCHEDULER_NEWTHREAD)]
-        public static IScheduler NewThread
-        {
-            get
-            {
-                return s_newThread.Value;
-            }
-        }
+        public static IScheduler NewThread => s_newThread.Value;
 
         private static Lazy<IScheduler> s_taskPool = new Lazy<IScheduler>(() => Initialize("TaskPool"));
 
@@ -123,13 +82,7 @@ namespace System.Reactive.Concurrency
         /// Gets a scheduler that schedules work on Task Parallel Library (TPL) task pool using the default TaskScheduler.
         /// </summary>
         [Obsolete(Constants_Core.OBSOLETE_SCHEDULER_TASKPOOL)]
-        public static IScheduler TaskPool
-        {
-            get
-            {
-                return s_taskPool.Value;
-            }
-        }
+        public static IScheduler TaskPool => s_taskPool.Value;
 
         private static IScheduler Initialize(string name)
         {

+ 5 - 5
Rx.NET/Source/src/System.Reactive/Concurrency/SchedulerDefaults.cs

@@ -6,10 +6,10 @@ namespace System.Reactive.Concurrency
 {
     internal static class SchedulerDefaults
     {
-        internal static IScheduler ConstantTimeOperations { get { return ImmediateScheduler.Instance; } }
-        internal static IScheduler TailRecursion { get { return ImmediateScheduler.Instance; } }
-        internal static IScheduler Iteration { get { return CurrentThreadScheduler.Instance; } }
-        internal static IScheduler TimeBasedOperations { get { return DefaultScheduler.Instance; } }
-        internal static IScheduler AsyncConversions { get { return DefaultScheduler.Instance; } }
+        internal static IScheduler ConstantTimeOperations => ImmediateScheduler.Instance;
+        internal static IScheduler TailRecursion => ImmediateScheduler.Instance;
+        internal static IScheduler Iteration => CurrentThreadScheduler.Instance;
+        internal static IScheduler TimeBasedOperations => DefaultScheduler.Instance;
+        internal static IScheduler AsyncConversions => DefaultScheduler.Instance;
     }
 }

+ 5 - 15
Rx.NET/Source/src/System.Reactive/Concurrency/SchedulerOperation.cs

@@ -53,8 +53,7 @@ namespace System.Reactive.Concurrency
     /// (Infrastructure) Scheduler operation awaiter type used by the code generated for C# await and Visual Basic Await expressions.
     /// </summary>
     [EditorBrowsable(EditorBrowsableState.Never)]
-    public sealed class SchedulerOperationAwaiter
-        : INotifyCompletion
+    public sealed class SchedulerOperationAwaiter : INotifyCompletion
     {
         private readonly Func<Action, IDisposable> _schedule;
         private readonly CancellationToken _cancellationToken;
@@ -76,18 +75,12 @@ namespace System.Reactive.Concurrency
         /// <summary>
         /// Indicates whether the scheduler operation has completed. Returns false unless cancellation was already requested.
         /// </summary>
-        public bool IsCompleted
-        {
-            get { return _cancellationToken.IsCancellationRequested; }
-        }
+        public bool IsCompleted => _cancellationToken.IsCancellationRequested;
 
         /// <summary>
         /// Completes the scheduler operation, throwing an OperationCanceledException in case cancellation was requested.
         /// </summary>
-        public void GetResult()
-        {
-            _cancellationToken.ThrowIfCancellationRequested();
-        }
+        public void GetResult() => _cancellationToken.ThrowIfCancellationRequested();
 
         /// <summary>
         /// Registers the continuation with the scheduler operation.
@@ -147,11 +140,8 @@ namespace System.Reactive.Concurrency
 
         private void Cancel()
         {
-            var w = _work;
-            if (w != null)
-                w.Dispose();
-
+            _work?.Dispose();
             _continuation?.Invoke();
         }
     }
-}
+}

+ 5 - 20
Rx.NET/Source/src/System.Reactive/Concurrency/SchedulerQueue.cs

@@ -39,13 +39,7 @@ namespace System.Reactive.Concurrency
         /// <summary>
         /// Gets the number of scheduled items in the scheduler queue.
         /// </summary>
-        public int Count
-        {
-            get
-            {
-                return _queue.Count;
-            }
-        }
+        public int Count => _queue.Count;
 
         /// <summary>
         /// Enqueues the specified work item to be scheduled.
@@ -60,28 +54,19 @@ namespace System.Reactive.Concurrency
         /// Removes the specified work item from the scheduler queue.
         /// </summary>
         /// <param name="scheduledItem">Work item to be removed from the scheduler queue.</param>
-        /// <returns>true if the item was found; false otherwise.</returns>
-        public bool Remove(ScheduledItem<TAbsolute> scheduledItem)
-        {
-            return _queue.Remove(scheduledItem);
-        }
+        /// <returns><c>true</c> if the item was found; <c>false</c> otherwise.</returns>
+        public bool Remove(ScheduledItem<TAbsolute> scheduledItem) => _queue.Remove(scheduledItem);
 
         /// <summary>
         /// Dequeues the next work item from the scheduler queue.
         /// </summary>
         /// <returns>Next work item in the scheduler queue (removed).</returns>
-        public ScheduledItem<TAbsolute> Dequeue()
-        {
-            return _queue.Dequeue();
-        }
+        public ScheduledItem<TAbsolute> Dequeue() => _queue.Dequeue();
 
         /// <summary>
         /// Peeks the next work item in the scheduler queue.
         /// </summary>
         /// <returns>Next work item in the scheduler queue (not removed).</returns>
-        public ScheduledItem<TAbsolute> Peek()
-        {
-            return _queue.Peek();
-        }
+        public ScheduledItem<TAbsolute> Peek() => _queue.Peek();
     }
 }

+ 1 - 4
Rx.NET/Source/src/System.Reactive/Concurrency/SchedulerWrapper.cs

@@ -23,10 +23,7 @@ namespace System.Reactive.Concurrency
             _cache = cache;
         }
 
-        public DateTimeOffset Now
-        {
-            get { return _scheduler.Now; }
-        }
+        public DateTimeOffset Now => _scheduler.Now;
 
         public IDisposable Schedule<TState>(TState state, Func<IScheduler, TState, IDisposable> action)
         {

+ 8 - 8
Rx.NET/Source/src/System.Reactive/Concurrency/Synchronization.ObserveOn.cs

@@ -8,7 +8,7 @@ using System.Threading;
 
 namespace System.Reactive.Concurrency
 {
-    class ObserveOn<TSource> : Producer<TSource>
+    internal sealed class ObserveOn<TSource> : Producer<TSource>
     {
         private readonly IObservable<TSource> _source;
         private readonly IScheduler _scheduler;
@@ -43,7 +43,7 @@ namespace System.Reactive.Concurrency
             }
         }
 
-        class ObserveOnSink : Sink<TSource>, IObserver<TSource>
+        private sealed class ObserveOnSink : Sink<TSource>, IObserver<TSource>
         {
             private readonly ObserveOn<TSource> _parent;
 
@@ -85,24 +85,24 @@ namespace System.Reactive.Concurrency
 
             public void OnCompleted()
             {
-                _parent._context.Post(OnCompletedPosted, null);
+                _parent._context.Post(OnCompletedPosted, state: null);
             }
 
             private void OnNextPosted(object value)
             {
-                base._observer.OnNext((TSource)value);
+                _observer.OnNext((TSource)value);
             }
 
             private void OnErrorPosted(object error)
             {
-                base._observer.OnError((Exception)error);
-                base.Dispose();
+                _observer.OnError((Exception)error);
+                Dispose();
             }
 
             private void OnCompletedPosted(object ignored)
             {
-                base._observer.OnCompleted();
-                base.Dispose();
+                _observer.OnCompleted();
+                Dispose();
             }
         }
     }

+ 7 - 7
Rx.NET/Source/src/System.Reactive/Concurrency/Synchronization.Synchronize.cs

@@ -5,7 +5,7 @@
 #if !NO_PERF
 namespace System.Reactive.Concurrency
 {
-    class Synchronize<TSource> : Producer<TSource>
+    internal sealed class Synchronize<TSource> : Producer<TSource>
     {
         private readonly IObservable<TSource> _source;
         private readonly object _gate;
@@ -29,7 +29,7 @@ namespace System.Reactive.Concurrency
             return _source.SubscribeSafe(sink);
         }
 
-        class _ : Sink<TSource>, IObserver<TSource>
+        private sealed class _ : Sink<TSource>, IObserver<TSource>
         {
             private readonly Synchronize<TSource> _parent;
             private readonly object _gate;
@@ -45,7 +45,7 @@ namespace System.Reactive.Concurrency
             {
                 lock (_gate)
                 {
-                    base._observer.OnNext(value);
+                    _observer.OnNext(value);
                 }
             }
 
@@ -53,8 +53,8 @@ namespace System.Reactive.Concurrency
             {
                 lock (_gate)
                 {
-                    base._observer.OnError(error);
-                    base.Dispose();
+                    _observer.OnError(error);
+                    Dispose();
                 }
             }
 
@@ -62,8 +62,8 @@ namespace System.Reactive.Concurrency
             {
                 lock (_gate)
                 {
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    _observer.OnCompleted();
+                    Dispose();
                 }
             }
         }

+ 8 - 6
Rx.NET/Source/src/System.Reactive/Concurrency/Synchronization.cs

@@ -23,7 +23,7 @@ namespace System.Reactive.Concurrency
         /// <param name="source">Source sequence.</param>
         /// <param name="scheduler">Scheduler to perform subscription and unsubscription actions on.</param>
         /// <returns>The source sequence whose subscriptions and unsubscriptions happen on the specified scheduler.</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is <c>null</c>.</exception>
         /// <remarks>
         /// Only the side-effects of subscribing to the source sequence and disposing subscriptions to the source sequence are run on the specified scheduler.
         /// In order to invoke observer callbacks on the specified scheduler, e.g. to offload callback processing to a dedicated thread, use <see cref="Synchronization.ObserveOn{TSource}(IObservable{TSource}, IScheduler)"/>.
@@ -57,7 +57,7 @@ namespace System.Reactive.Concurrency
         /// <param name="source">Source sequence.</param>
         /// <param name="context">Synchronization context to perform subscription and unsubscription actions on.</param>
         /// <returns>The source sequence whose subscriptions and unsubscriptions happen on the specified synchronization context.</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="context"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="context"/> is <c>null</c>.</exception>
         /// <remarks>
         /// Only the side-effects of subscribing to the source sequence and disposing subscriptions to the source sequence are run on the specified synchronization context.
         /// In order to invoke observer callbacks on the specified synchronization context, e.g. to post callbacks to a UI thread represented by the synchronization context, use <see cref="Synchronization.ObserveOn{TSource}(IObservable{TSource}, SynchronizationContext)"/>.
@@ -75,7 +75,9 @@ namespace System.Reactive.Concurrency
                 context.PostWithStartComplete(() =>
                 {
                     if (!subscription.IsDisposed)
+                    {
                         subscription.Disposable = new ContextDisposable(context, source.SubscribeSafe(observer));
+                    }
                 });
                 return subscription;
             });
@@ -92,7 +94,7 @@ namespace System.Reactive.Concurrency
         /// <param name="source">Source sequence.</param>
         /// <param name="scheduler">Scheduler to notify observers on.</param>
         /// <returns>The source sequence whose observations happen on the specified scheduler.</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is <c>null</c>.</exception>
         public static IObservable<TSource> ObserveOn<TSource>(IObservable<TSource> source, IScheduler scheduler)
         {
             if (source == null)
@@ -114,7 +116,7 @@ namespace System.Reactive.Concurrency
         /// <param name="source">Source sequence.</param>
         /// <param name="context">Synchronization context to notify observers on.</param>
         /// <returns>The source sequence whose observations happen on the specified synchronization context.</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="context"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="context"/> is <c>null</c>.</exception>
         public static IObservable<TSource> ObserveOn<TSource>(IObservable<TSource> source, SynchronizationContext context)
         {
             if (source == null)
@@ -160,7 +162,7 @@ namespace System.Reactive.Concurrency
         /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
         /// <param name="source">Source sequence.</param>
         /// <returns>The source sequence whose outgoing calls to observers are synchronized.</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="source"/> is <c>null</c>.</exception>
         public static IObservable<TSource> Synchronize<TSource>(IObservable<TSource> source)
         {
             if (source == null)
@@ -184,7 +186,7 @@ namespace System.Reactive.Concurrency
         /// <param name="source">Source sequence.</param>
         /// <param name="gate">Gate object to synchronize each observer call on.</param>
         /// <returns>The source sequence whose outgoing calls to observers are synchronized on the given gate object.</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="gate"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="gate"/> is <c>null</c>.</exception>
         public static IObservable<TSource> Synchronize<TSource>(IObservable<TSource> source, object gate)
         {
             if (source == null)

+ 8 - 4
Rx.NET/Source/src/System.Reactive/Concurrency/SynchronizationContextScheduler.cs

@@ -19,7 +19,7 @@ namespace System.Reactive.Concurrency
         /// Creates an object that schedules units of work on the provided <see cref="SynchronizationContext"/>.
         /// </summary>
         /// <param name="context">Synchronization context to schedule units of work on.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="context"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="context"/> is <c>null</c>.</exception>
         public SynchronizationContextScheduler(SynchronizationContext context)
         {
             if (context == null)
@@ -34,7 +34,7 @@ namespace System.Reactive.Concurrency
         /// </summary>
         /// <param name="context">Synchronization context to schedule units of work on.</param>
         /// <param name="alwaysPost">Configures whether scheduling always posts to the synchronization context, regardless whether the caller is on the same synchronization context.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="context"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="context"/> is <c>null</c>.</exception>
         public SynchronizationContextScheduler(SynchronizationContext context, bool alwaysPost)
         {
             if (context == null)
@@ -51,7 +51,7 @@ namespace System.Reactive.Concurrency
         /// <param name="state">State passed to the action to be executed.</param>
         /// <param name="action">Action to be executed.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
         public override IDisposable Schedule<TState>(TState state, Func<IScheduler, TState, IDisposable> action)
         {
             if (action == null)
@@ -68,7 +68,9 @@ namespace System.Reactive.Concurrency
                 _context.PostWithStartComplete(() =>
                 {
                     if (!d.IsDisposed)
+                    {
                         d.Disposable = action(this, state);
+                    }
                 });
             }
 
@@ -83,7 +85,7 @@ namespace System.Reactive.Concurrency
         /// <param name="action">Action to be executed.</param>
         /// <param name="dueTime">Relative time after which to execute the action.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
         public override IDisposable Schedule<TState>(TState state, TimeSpan dueTime, Func<IScheduler, TState, IDisposable> action)
         {
             if (action == null)
@@ -91,7 +93,9 @@ namespace System.Reactive.Concurrency
 
             var dt = Scheduler.Normalize(dueTime);
             if (dt.Ticks == 0)
+            {
                 return Schedule(state, action);
+            }
 
             return DefaultScheduler.Instance.Schedule(state, dt, (_, state1) => Schedule(state1, action));
         }

+ 1 - 1
Rx.NET/Source/src/System.Reactive/Concurrency/TaskHelpers.cs

@@ -7,7 +7,7 @@ using System.Threading.Tasks;
 
 namespace System.Reactive.Concurrency
 {
-    static class TaskHelpers
+    internal static class TaskHelpers
     {
         private const int MAX_DELAY = int.MaxValue;
 

+ 18 - 15
Rx.NET/Source/src/System.Reactive/Concurrency/TaskPoolScheduler.cs

@@ -18,10 +18,10 @@ namespace System.Reactive.Concurrency
         private readonly TaskFactory taskFactory;
 
         /// <summary>
-        /// Creates an object that schedules units of work using the provided TaskFactory.
+        /// Creates an object that schedules units of work using the provided <see cref="TaskFactory"/>.
         /// </summary>
         /// <param name="taskFactory">Task factory used to create tasks to run units of work.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="taskFactory"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="taskFactory"/> is <c>null</c>.</exception>
         public TaskPoolScheduler(TaskFactory taskFactory)
         {
             if (taskFactory == null)
@@ -31,15 +31,9 @@ namespace System.Reactive.Concurrency
         }
 
         /// <summary>
-        /// Gets an instance of this scheduler that uses the default TaskScheduler.
+        /// Gets an instance of this scheduler that uses the default <see cref="TaskScheduler"/>.
         /// </summary>
-        public static TaskPoolScheduler Default
-        {
-            get
-            {
-                return s_instance.Value;
-            }
-        }
+        public static TaskPoolScheduler Default => s_instance.Value;
 
         /// <summary>
         /// Schedules an action to be executed.
@@ -48,7 +42,7 @@ namespace System.Reactive.Concurrency
         /// <param name="state">State passed to the action to be executed.</param>
         /// <param name="action">Action to be executed.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
         public override IDisposable Schedule<TState>(TState state, Func<IScheduler, TState, IDisposable> action)
         {
             if (action == null)
@@ -96,7 +90,7 @@ namespace System.Reactive.Concurrency
         /// <param name="action">Action to be executed.</param>
         /// <param name="dueTime">Relative time after which to execute the action.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
         public override IDisposable Schedule<TState>(TState state, TimeSpan dueTime, Func<IScheduler, TState, IDisposable> action)
         {
             if (action == null)
@@ -104,8 +98,15 @@ namespace System.Reactive.Concurrency
 
             var dt = Scheduler.Normalize(dueTime);
             if (dt.Ticks == 0)
+            {
                 return Schedule(state, action);
+            }
+
+            return ScheduleSlow(state, dt, action);
+        }
 
+        private IDisposable ScheduleSlow<TState>(TState state, TimeSpan dueTime, Func<IScheduler, TState, IDisposable> action)
+        {
             var d = new MultipleAssignmentDisposable();
 
             var ct = new CancellationDisposable();
@@ -114,7 +115,9 @@ namespace System.Reactive.Concurrency
             TaskHelpers.Delay(dueTime, ct.Token).ContinueWith(_ =>
             {
                 if (!d.IsDisposed)
+                {
                     d.Disposable = action(this, state);
+                }
             }, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.OnlyOnRanToCompletion, taskFactory.Scheduler);
 
             return d;
@@ -127,7 +130,7 @@ namespace System.Reactive.Concurrency
         /// <param name="state">State passed to the action to be executed.</param>
         /// <param name="action">Action to be executed.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
         public IDisposable ScheduleLongRunning<TState>(TState state, Action<TState, ICancelable> action)
         {
             var d = new BooleanDisposable();
@@ -167,8 +170,8 @@ namespace System.Reactive.Concurrency
         /// <param name="period">Period for running the work periodically.</param>
         /// <param name="action">Action to be executed, potentially updating the state.</param>
         /// <returns>The disposable object used to cancel the scheduled recurring action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="period"/> is less than TimeSpan.Zero.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="period"/> is less than <see cref="TimeSpan.Zero"/>.</exception>
         public IDisposable SchedulePeriodic<TState>(TState state, TimeSpan period, Func<TState, TState> action)
         {
             if (period < TimeSpan.Zero)

+ 6 - 7
Rx.NET/Source/src/System.Reactive/Concurrency/Thread.Stub.cs

@@ -3,9 +3,11 @@
 // See the LICENSE file in the project root for more information. 
 
 #if NO_THREAD
+using System.Threading.Tasks;
+
 namespace System.Reactive.Concurrency
 {
-    class Thread
+    internal sealed class Thread
     {
         private readonly ThreadStart _start;
 
@@ -19,15 +21,12 @@ namespace System.Reactive.Concurrency
 
         public void Start()
         {
-            System.Threading.Tasks.Task.Factory.StartNew(Run, System.Threading.Tasks.TaskCreationOptions.LongRunning);
+            Task.Factory.StartNew(Run, TaskCreationOptions.LongRunning);
         }
 
-        private void Run()
-        {
-            _start();
-        }
+        private void Run() => _start();
     }
 
     delegate void ThreadStart();
 }
-#endif
+#endif

+ 21 - 25
Rx.NET/Source/src/System.Reactive/Concurrency/ThreadPoolScheduler.Windows.cs

@@ -3,7 +3,6 @@
 // See the LICENSE file in the project root for more information. 
 
 #if WINDOWS
-using System.Reactive.Concurrency;
 using System.Reactive.Disposables;
 using Windows.System.Threading;
 
@@ -16,8 +15,6 @@ namespace System.Reactive.Concurrency
     [CLSCompliant(false)]
     public sealed class ThreadPoolScheduler : LocalScheduler, ISchedulerPeriodic
     {
-        private readonly WorkItemPriority _priority;
-        private readonly WorkItemOptions _options;
         private static Lazy<ThreadPoolScheduler> s_default = new Lazy<ThreadPoolScheduler>(() => new ThreadPoolScheduler());
 
         /// <summary>
@@ -33,8 +30,8 @@ namespace System.Reactive.Concurrency
         /// <param name="priority">Priority for scheduled units of work.</param>
         public ThreadPoolScheduler(WorkItemPriority priority)
         {
-            _priority = priority;
-            _options = WorkItemOptions.None;
+            Priority = priority;
+            Options = WorkItemOptions.None;
         }
 
         /// <summary>
@@ -44,36 +41,24 @@ namespace System.Reactive.Concurrency
         /// <param name="options">Options that configure how work is scheduled.</param>
         public ThreadPoolScheduler(WorkItemPriority priority, WorkItemOptions options)
         {
-            _priority = priority;
-            _options = options;
+            Priority = priority;
+            Options = options;
         }
 
         /// <summary>
         /// Gets the singleton instance of the Windows Runtime thread pool scheduler.
         /// </summary>
-        public static ThreadPoolScheduler Default
-        {
-            get
-            {
-                return s_default.Value;
-            }
-        }
+        public static ThreadPoolScheduler Default => s_default.Value;
 
         /// <summary>
         /// Gets the priority at which work is scheduled.
         /// </summary>
-        public WorkItemPriority Priority
-        {
-            get { return _priority; }
-        }
+        public WorkItemPriority Priority { get; }
 
         /// <summary>
         /// Gets the options that configure how work is scheduled.
         /// </summary>
-        public WorkItemOptions Options
-        {
-            get { return _options; }
-        }
+        public WorkItemOptions Options { get; }
 
         /// <summary>
         /// Schedules an action to be executed.
@@ -93,8 +78,10 @@ namespace System.Reactive.Concurrency
             var res = global::Windows.System.Threading.ThreadPool.RunAsync(iaa =>
             {
                 if (!d.IsDisposed)
+                {
                     d.Disposable = action(this, state);
-            }, _priority, _options);
+                }
+            }, Priority, Options);
 
             return new CompositeDisposable(
                 d,
@@ -119,17 +106,26 @@ namespace System.Reactive.Concurrency
             var dt = Scheduler.Normalize(dueTime);
 
             if (dt.Ticks == 0)
+            {
                 return Schedule(state, action);
+            }
 
+            return ScheduleSlow(state, dt, action);
+        }
+
+        private IDisposable ScheduleSlow<TState>(TState state, TimeSpan dueTime, Func<IScheduler, TState, IDisposable> action)
+        {
             var d = new SingleAssignmentDisposable();
 
             var res = global::Windows.System.Threading.ThreadPoolTimer.CreateTimer(
                 tpt =>
                 {
                     if (!d.IsDisposed)
+                    {
                         d.Disposable = action(this, state);
+                    }
                 },
-                dt
+                dueTime
             );
 
             return new CompositeDisposable(
@@ -184,4 +180,4 @@ namespace System.Reactive.Concurrency
         }
     }
 }
-#endif
+#endif

+ 17 - 28
Rx.NET/Source/src/System.Reactive/Concurrency/ThreadPoolScheduler.cs

@@ -21,15 +21,9 @@ namespace System.Reactive.Concurrency
         /// <summary>
         /// Gets the singleton instance of the CLR thread pool scheduler.
         /// </summary>
-        public static ThreadPoolScheduler Instance
-        {
-            get
-            {
-                return s_instance.Value;
-            }
-        }
+        public static ThreadPoolScheduler Instance => s_instance.Value;
 
-        ThreadPoolScheduler()
+        private ThreadPoolScheduler()
         {
         }
 
@@ -40,7 +34,7 @@ namespace System.Reactive.Concurrency
         /// <param name="state">State passed to the action to be executed.</param>
         /// <param name="action">Action to be executed.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
         public override IDisposable Schedule<TState>(TState state, Func<IScheduler, TState, IDisposable> action)
         {
             if (action == null)
@@ -51,7 +45,9 @@ namespace System.Reactive.Concurrency
             ThreadPool.QueueUserWorkItem(_ =>
             {
                 if (!d.IsDisposed)
+                {
                     d.Disposable = action(this, state);
+                }
             }, null);
 
             return d;
@@ -65,7 +61,7 @@ namespace System.Reactive.Concurrency
         /// <param name="action">Action to be executed.</param>
         /// <param name="dueTime">Relative time after which to execute the action.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
         public override IDisposable Schedule<TState>(TState state, TimeSpan dueTime, Func<IScheduler, TState, IDisposable> action)
         {
             if (action == null)
@@ -73,7 +69,9 @@ namespace System.Reactive.Concurrency
 
             var dt = Scheduler.Normalize(dueTime);
             if (dt.Ticks == 0)
+            {
                 return Schedule(state, action);
+            }
 
             return new Timer<TState>(this, state, dt, action);
         }
@@ -85,7 +83,7 @@ namespace System.Reactive.Concurrency
         /// <param name="state">State passed to the action to be executed.</param>
         /// <param name="action">Action to be executed.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
         public IDisposable ScheduleLongRunning<TState>(TState state, Action<TState, ICancelable> action)
         {
             if (action == null)
@@ -116,7 +114,7 @@ namespace System.Reactive.Concurrency
         /// <param name="period">Period for running the work periodically.</param>
         /// <param name="action">Action to be executed, potentially updating the state.</param>
         /// <returns>The disposable object used to cancel the scheduled recurring action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
         /// <exception cref="ArgumentOutOfRangeException"><paramref name="period"/> is less than zero.</exception>
         public IDisposable SchedulePeriodic<TState>(TState state, TimeSpan period, Func<TState, TState> action)
         {
@@ -135,7 +133,7 @@ namespace System.Reactive.Concurrency
             }
         }
 
-        sealed class FastPeriodicTimer<TState> : IDisposable
+        private sealed class FastPeriodicTimer<TState> : IDisposable
         {
             private TState _state;
             private Func<TState, TState> _action;
@@ -170,7 +168,7 @@ namespace System.Reactive.Concurrency
         // below and its timer rooting behavior.
         //
 
-        sealed class Timer<TState> : IDisposable
+        private sealed class Timer<TState> : IDisposable
         {
             private readonly MultipleAssignmentDisposable _disposable;
 
@@ -214,15 +212,9 @@ namespace System.Reactive.Concurrency
                 }
             }
 
-            private bool IsTimerAssigned()
-            {
-                return _timer != null;
-            }
+            private bool IsTimerAssigned() => _timer != null;
 
-            public void Dispose()
-            {
-                _disposable.Dispose();
-            }
+            public void Dispose() => _disposable.Dispose();
 
             private void Stop()
             {
@@ -236,13 +228,10 @@ namespace System.Reactive.Concurrency
                 }
             }
 
-            private IDisposable Nop(IScheduler scheduler, TState state)
-            {
-                return Disposable.Empty;
-            }
+            private IDisposable Nop(IScheduler scheduler, TState state) => Disposable.Empty;
         }
 
-        sealed class PeriodicTimer<TState> : IDisposable
+        private sealed class PeriodicTimer<TState> : IDisposable
         {
             private TState _state;
             private Func<TState, TState> _action;
@@ -287,4 +276,4 @@ namespace System.Reactive.Concurrency
         }
     }
 }
-#endif
+#endif

+ 5 - 5
Rx.NET/Source/src/System.Reactive/Concurrency/VirtualTimeScheduler.Extensions.cs

@@ -12,7 +12,7 @@ namespace System.Reactive.Concurrency
     public static class VirtualTimeSchedulerExtensions
     {
         /// <summary>
-        /// Schedules an action to be executed at dueTime.
+        /// Schedules an action to be executed at <paramref name="dueTime"/>.
         /// </summary>
         /// <typeparam name="TAbsolute">Absolute time representation type.</typeparam>
         /// <typeparam name="TRelative">Relative time representation type.</typeparam>
@@ -20,7 +20,7 @@ namespace System.Reactive.Concurrency
         /// <param name="dueTime">Relative time after which to execute the action.</param>
         /// <param name="action">Action to be executed.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is <c>null</c>.</exception>
         public static IDisposable ScheduleRelative<TAbsolute, TRelative>(this VirtualTimeSchedulerBase<TAbsolute, TRelative> scheduler, TRelative dueTime, Action action)
             where TAbsolute : IComparable<TAbsolute>
         {
@@ -33,7 +33,7 @@ namespace System.Reactive.Concurrency
         }
 
         /// <summary>
-        /// Schedules an action to be executed at dueTime.
+        /// Schedules an action to be executed at <paramref name="dueTime"/>.
         /// </summary>
         /// <typeparam name="TAbsolute">Absolute time representation type.</typeparam>
         /// <typeparam name="TRelative">Relative time representation type.</typeparam>
@@ -41,7 +41,7 @@ namespace System.Reactive.Concurrency
         /// <param name="dueTime">Absolute time at which to execute the action.</param>
         /// <param name="action">Action to be executed.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is <c>null</c>.</exception>
         public static IDisposable ScheduleAbsolute<TAbsolute, TRelative>(this VirtualTimeSchedulerBase<TAbsolute, TRelative> scheduler, TAbsolute dueTime, Action action)
             where TAbsolute : IComparable<TAbsolute>
         {
@@ -53,7 +53,7 @@ namespace System.Reactive.Concurrency
             return scheduler.ScheduleAbsolute(action, dueTime, Invoke);
         }
 
-        static IDisposable Invoke(IScheduler scheduler, Action action)
+        private static IDisposable Invoke(IScheduler scheduler, Action action)
         {
             action();
             return Disposable.Empty;

+ 28 - 31
Rx.NET/Source/src/System.Reactive/Concurrency/VirtualTimeScheduler.cs

@@ -29,7 +29,7 @@ namespace System.Reactive.Concurrency
         /// </summary>
         /// <param name="initialClock">Initial value for the clock.</param>
         /// <param name="comparer">Comparer to determine causality of events based on absolute time.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="comparer"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="comparer"/> is <c>null</c>.</exception>
         protected VirtualTimeSchedulerBase(TAbsolute initialClock, IComparer<TAbsolute> comparer)
         {
             if (comparer == null)
@@ -64,20 +64,12 @@ namespace System.Reactive.Concurrency
         /// <summary>
         /// Gets whether the scheduler is enabled to run work.
         /// </summary>
-        public bool IsEnabled
-        {
-            get;
-            private set;
-        }
+        public bool IsEnabled { get; private set; }
 
         /// <summary>
         /// Gets the comparer used to compare absolute time values.
         /// </summary>
-        protected IComparer<TAbsolute> Comparer
-        {
-            get;
-            private set;
-        }
+        protected IComparer<TAbsolute> Comparer { get; }
 
         /// <summary>
         /// Schedules an action to be executed at dueTime.
@@ -114,7 +106,7 @@ namespace System.Reactive.Concurrency
         /// <param name="state">State passed to the action to be executed.</param>
         /// <param name="action">Action to be executed.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
         public IDisposable Schedule<TState>(TState state, Func<IScheduler, TState, IDisposable> action)
         {
             if (action == null)
@@ -131,7 +123,7 @@ namespace System.Reactive.Concurrency
         /// <param name="dueTime">Relative time after which to execute the action.</param>
         /// <param name="action">Action to be executed.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
         public IDisposable Schedule<TState>(TState state, TimeSpan dueTime, Func<IScheduler, TState, IDisposable> action)
         {
             if (action == null)
@@ -148,7 +140,7 @@ namespace System.Reactive.Concurrency
         /// <param name="dueTime">Absolute time at which to execute the action.</param>
         /// <param name="action">Action to be executed.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
         public IDisposable Schedule<TState>(TState state, DateTimeOffset dueTime, Func<IScheduler, TState, IDisposable> action)
         {
             if (action == null)
@@ -171,11 +163,16 @@ namespace System.Reactive.Concurrency
                     if (next != null)
                     {
                         if (Comparer.Compare(next.DueTime, Clock) > 0)
+                        {
                             Clock = next.DueTime;
+                        }
+
                         next.Invoke();
                     }
                     else
+                    {
                         IsEnabled = false;
+                    }
                 } while (IsEnabled);
             }
         }
@@ -212,18 +209,23 @@ namespace System.Reactive.Concurrency
                     if (next != null && Comparer.Compare(next.DueTime, time) <= 0)
                     {
                         if (Comparer.Compare(next.DueTime, Clock) > 0)
+                        {
                             Clock = next.DueTime;
+                        }
+
                         next.Invoke();
                     }
                     else
+                    {
                         IsEnabled = false;
+                    }
                 } while (IsEnabled);
 
                 Clock = time;
             }
             else
             {
-                throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Strings_Linq.CANT_ADVANCE_WHILE_RUNNING, "AdvanceTo"));
+                throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Strings_Linq.CANT_ADVANCE_WHILE_RUNNING, nameof(AdvanceTo)));
             }
         }
 
@@ -250,7 +252,7 @@ namespace System.Reactive.Concurrency
             }
             else
             {
-                throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Strings_Linq.CANT_ADVANCE_WHILE_RUNNING, "AdvanceBy"));
+                throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Strings_Linq.CANT_ADVANCE_WHILE_RUNNING, nameof(AdvanceBy)));
             }
         }
 
@@ -282,10 +284,7 @@ namespace System.Reactive.Concurrency
         /// <summary>
         /// Gets the scheduler's notion of current time.
         /// </summary>
-        public DateTimeOffset Now
-        {
-            get { return ToDateTimeOffset(Clock); }
-        }
+        public DateTimeOffset Now => ToDateTimeOffset(Clock);
 
         /// <summary>
         /// Gets the next scheduled item to be executed.
@@ -294,10 +293,7 @@ namespace System.Reactive.Concurrency
         [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "By design. Side-effecting operation to retrieve the next element.")]
         protected abstract IScheduledItem<TAbsolute> GetNext();
 
-        object IServiceProvider.GetService(Type serviceType)
-        {
-            return GetService(serviceType);
-        }
+        object IServiceProvider.GetService(Type serviceType) => GetService(serviceType);
 
         /// <summary>
         /// Discovers scheduler services by interface type. The base class implementation supports
@@ -324,7 +320,7 @@ namespace System.Reactive.Concurrency
             return new VirtualTimeStopwatch(() => ToDateTimeOffset(Clock) - start);
         }
 
-        class VirtualTimeStopwatch : IStopwatch
+        private sealed class VirtualTimeStopwatch : IStopwatch
         {
             private readonly Func<TimeSpan> _getElapsed;
 
@@ -333,10 +329,7 @@ namespace System.Reactive.Concurrency
                 _getElapsed = getElapsed;
             }
 
-            public TimeSpan Elapsed
-            {
-                get { return _getElapsed(); }
-            }
+            public TimeSpan Elapsed => _getElapsed();
         }
     }
 
@@ -363,7 +356,7 @@ namespace System.Reactive.Concurrency
         /// </summary>
         /// <param name="initialClock">Initial value for the clock.</param>
         /// <param name="comparer">Comparer to determine causality of events based on absolute time.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="comparer"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="comparer"/> is <c>null</c>.</exception>
         protected VirtualTimeScheduler(TAbsolute initialClock, IComparer<TAbsolute> comparer)
             : base(initialClock, comparer)
         {
@@ -381,9 +374,13 @@ namespace System.Reactive.Concurrency
                 {
                     var next = queue.Peek();
                     if (next.IsCanceled)
+                    {
                         queue.Dequeue();
+                    }
                     else
+                    {
                         return next;
+                    }
                 }
             }
 
@@ -398,7 +395,7 @@ namespace System.Reactive.Concurrency
         /// <param name="action">Action to be executed.</param>
         /// <param name="dueTime">Absolute time at which to execute the action.</param>
         /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
         public override IDisposable ScheduleAbsolute<TState>(TState state, TAbsolute dueTime, Func<IScheduler, TState, IDisposable> action)
         {
             if (action == null)

+ 1 - 1
Rx.NET/Source/src/System.Reactive/Platforms/Windows/Concurrency/CoreDispatcherScheduler.cs

@@ -203,7 +203,7 @@ namespace System.Reactive.Concurrency
         /// <param name="action">Action to be executed, potentially updating the state.</param>
         /// <returns>The disposable object used to cancel the scheduled recurring action (best effort).</returns>
         /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="period"/> is less than TimeSpan.Zero.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="period"/> is less than <see cref="TimeSpan.Zero"/>.</exception>
         public IDisposable SchedulePeriodic<TState>(TState state, TimeSpan period, Func<TState, TState> action)
         {
             //

+ 1 - 1
Rx.NET/Source/src/System.Reactive/Platforms/Windows/Concurrency/DispatcherScheduler.cs

@@ -192,7 +192,7 @@ namespace System.Reactive.Concurrency
         /// <param name="action">Action to be executed, potentially updating the state.</param>
         /// <returns>The disposable object used to cancel the scheduled recurring action (best effort).</returns>
         /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="period"/> is less than TimeSpan.Zero.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="period"/> is less than <see cref="TimeSpan.Zero"/>.</exception>
         public IDisposable SchedulePeriodic<TState>(TState state, TimeSpan period, Func<TState, TState> action)
         {
             if (period < TimeSpan.Zero)