Răsfoiți Sursa

All timers now have the self-rooting behavior.

Bart De Smet 8 ani în urmă
părinte
comite
6931670c96

+ 6 - 6
Rx.NET/Source/Directory.build.targets

@@ -1,4 +1,4 @@
-<Project>  
+<Project>
   <!-- This has to be set in targets as the default props will overwrite -->
   <PropertyGroup>
     <DebugType>embedded</DebugType>
@@ -6,19 +6,19 @@
   
   <!-- This props all need to be set in targets as they depend on the values set earlier -->
   <PropertyGroup Condition="'$(TargetFramework)' == 'netstandard1.3'">
-    <DefineConstants>$(DefineConstants);NO_CODE_COVERAGE_ATTRIBUTE;HAS_WINRT;PREFER_ASYNC;USE_TIMER_SELF_ROOT;HAS_TPL46;NO_REMOTING;NO_SERIALIZABLE;CRIPPLED_REFLECTION</DefineConstants>
+    <DefineConstants>$(DefineConstants);NO_CODE_COVERAGE_ATTRIBUTE;HAS_WINRT;PREFER_ASYNC;HAS_TPL46;NO_REMOTING;NO_SERIALIZABLE;CRIPPLED_REFLECTION</DefineConstants>
   </PropertyGroup>
   <PropertyGroup Condition="'$(TargetFramework)' == 'net45'">
-    <DefineConstants>$(DefineConstants);HAS_WINRT;PREFER_ASYNC;USE_TIMER_SELF_ROOT;DESKTOPCLR</DefineConstants>
+    <DefineConstants>$(DefineConstants);HAS_WINRT;PREFER_ASYNC;DESKTOPCLR</DefineConstants>
   </PropertyGroup>
   <PropertyGroup Condition="'$(TargetFramework)' == 'net46'">
-    <DefineConstants>$(DefineConstants);HAS_WINRT;PREFER_ASYNC;USE_TIMER_SELF_ROOT;HAS_TPL46;DESKTOPCLR</DefineConstants>
+    <DefineConstants>$(DefineConstants);HAS_WINRT;PREFER_ASYNC;HAS_TPL46;DESKTOPCLR</DefineConstants>
   </PropertyGroup>
   <PropertyGroup Condition="'$(TargetFramework)' == 'uap10.0'">
-    <DefineConstants>$(DefineConstants);NO_CODE_COVERAGE_ATTRIBUTE;HAS_WINRT;PREFER_ASYNC;USE_TIMER_SELF_ROOT;HAS_TPL46;NO_REMOTING;NO_SERIALIZABLE;CRIPPLED_REFLECTION;NO_THREAD;WINDOWS</DefineConstants>
+    <DefineConstants>$(DefineConstants);NO_CODE_COVERAGE_ATTRIBUTE;HAS_WINRT;PREFER_ASYNC;HAS_TPL46;NO_REMOTING;NO_SERIALIZABLE;CRIPPLED_REFLECTION;NO_THREAD;WINDOWS</DefineConstants>
   </PropertyGroup>
   <PropertyGroup Condition="'$(TargetFramework)' == 'netcoreapp1.0' or '$(TargetFramework)' == 'netcoreapp1.1'">
-    <DefineConstants>$(DefineConstants);HAS_WINRT;PREFER_ASYNC;USE_TIMER_SELF_ROOT;HAS_TPL46;NO_REMOTING;NO_SERIALIZABLE;CRIPPLED_REFLECTION</DefineConstants>    
+    <DefineConstants>$(DefineConstants);HAS_WINRT;PREFER_ASYNC;HAS_TPL46;NO_REMOTING;NO_SERIALIZABLE;CRIPPLED_REFLECTION</DefineConstants>
   </PropertyGroup>
   
   <!-- UWP -->

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

@@ -85,8 +85,6 @@ namespace System.Reactive.Concurrency
             return dueTime;
         }
 
-#if USE_TIMER_SELF_ROOT
-
         //
         // Some historical context. In the early days of Rx, we discovered an issue with
         // the rooting of timers, causing them to get GC'ed even when the IDisposable of
@@ -153,6 +151,10 @@ namespace System.Reactive.Concurrency
         // for newer platforms where this no longer needed. We checked this on .NET Core
         // as well as .NET 4.0, and only #define this symbol for those platforms.
         //
+        // NB: 4/13/2017 - All target platforms for the 4.x release have the self-rooting
+        //                 behavior described here, so we removed the USE_TIMER_SELF_ROOT
+        //                 symbol.
+        //
 
         class Timer : IDisposable
         {
@@ -239,119 +241,6 @@ namespace System.Reactive.Concurrency
                 }
             }
         }
-#else
-        class Timer : IDisposable
-        {
-            //
-            // Note: the dictionary exists to "root" the timers so that they are not garbage collected and finalized while they are running.
-            //
-            private static readonly HashSet<System.Threading.Timer> s_timers = new HashSet<System.Threading.Timer>();
-
-            private Action<object> _action;
-            private System.Threading.Timer _timer;
-
-            private bool _hasAdded;
-            private bool _hasRemoved;
-
-            public Timer(Action<object> action, object state, TimeSpan dueTime)
-            {
-                _action = action;
-                _timer = new System.Threading.Timer(Tick, state, dueTime, TimeSpan.FromMilliseconds(System.Threading.Timeout.Infinite));
-
-                lock (s_timers)
-                {
-                    if (!_hasRemoved)
-                    {
-                        s_timers.Add(_timer);
-                        _hasAdded = true;
-                    }
-                }
-            }
-
-            private void Tick(object state)
-            {
-                try
-                {
-                    _action(state);
-                }
-                finally
-                {
-                    Dispose();
-                }
-            }
-
-            public void Dispose()
-            {
-                _action = Stubs<object>.Ignore;
-
-                var timer = default(System.Threading.Timer);
-
-                lock (s_timers)
-                {
-                    if (!_hasRemoved)
-                    {
-                        timer = _timer;
-                        _timer = null;
-
-                        if (_hasAdded && timer != null)
-                            s_timers.Remove(timer);
-
-                        _hasRemoved = true;
-                    }
-                }
-
-                if (timer != null)
-                    timer.Dispose();
-            }
-        }
-
-        class PeriodicTimer : IDisposable
-        {
-            //
-            // Note: the dictionary exists to "root" the timers so that they are not garbage collected and finalized while they are running.
-            //
-            private static readonly HashSet<System.Threading.Timer> s_timers = new HashSet<System.Threading.Timer>();
-
-            private Action _action;
-            private System.Threading.Timer _timer;
-
-            public PeriodicTimer(Action action, TimeSpan period)
-            {
-                _action = action;
-                _timer = new System.Threading.Timer(Tick, null, period, period);
-
-                lock (s_timers)
-                {
-                    s_timers.Add(_timer);
-                }
-            }
-
-            private void Tick(object state)
-            {
-                _action();
-            }
-
-            public void Dispose()
-            {
-                var timer = default(System.Threading.Timer);
-
-                lock (s_timers)
-                {
-                    timer = _timer;
-                    _timer = null;
-
-                    if (timer != null)
-                        s_timers.Remove(timer);
-                }
-
-                if (timer != null)
-                {
-                    timer.Dispose();
-                    _action = Stubs.Nop;
-                }
-            }
-        }
-#endif
 
         class FastPeriodicTimer : IDisposable
         {

+ 0 - 153
Rx.NET/Source/src/System.Reactive/Concurrency/ThreadPoolScheduler.cs

@@ -165,8 +165,6 @@ namespace System.Reactive.Concurrency
             }
         }
 
-#if USE_TIMER_SELF_ROOT
-
         //
         // See ConcurrencyAbstractionLayerImpl.cs for more information about the code
         // below and its timer rooting behavior.
@@ -287,157 +285,6 @@ namespace System.Reactive.Concurrency
                 }
             }
         }
-#else
-        abstract class Timer
-        {
-            //
-            // Note: the dictionary exists to "root" the timers so that they are not garbage collected and finalized while they are running.
-            //
-            protected static readonly HashSet<System.Threading.Timer> s_timers = new HashSet<System.Threading.Timer>();
-        }
-
-        sealed class Timer<TState> : Timer, IDisposable
-        {
-            private readonly MultipleAssignmentDisposable _disposable;
-
-            private readonly IScheduler _parent;
-            private readonly TState _state;
-
-            private Func<IScheduler, TState, IDisposable> _action;
-            private System.Threading.Timer _timer;
-
-            private bool _hasAdded;
-            private bool _hasRemoved;
-
-            public Timer(IScheduler parent, TState state, TimeSpan dueTime, Func<IScheduler, TState, IDisposable> action)
-            {
-                _disposable = new MultipleAssignmentDisposable();
-                _disposable.Disposable = Disposable.Create(Unroot);
-
-                _parent = parent;
-                _state = state;
-
-                _action = action;
-                _timer = new System.Threading.Timer(Tick, null, dueTime, TimeSpan.FromMilliseconds(System.Threading.Timeout.Infinite));
-
-                lock (s_timers)
-                {
-                    if (!_hasRemoved)
-                    {
-                        s_timers.Add(_timer);
-
-                        _hasAdded = true;
-                    }
-                }
-            }
-
-            private void Tick(object state)
-            {
-                try
-                {
-                    _disposable.Disposable = _action(_parent, _state);
-                }
-                finally
-                {
-                    Unroot();
-                }
-            }
-
-            private void Unroot()
-            {
-                _action = Nop;
-
-                var timer = default(System.Threading.Timer);
-
-                lock (s_timers)
-                {
-                    if (!_hasRemoved)
-                    {
-                        timer = _timer;
-                        _timer = null;
-
-                        if (_hasAdded && timer != null)
-                            s_timers.Remove(timer);
-
-                        _hasRemoved = true;
-                    }
-                }
-
-                if (timer != null)
-                    timer.Dispose();
-            }
-
-            private IDisposable Nop(IScheduler scheduler, TState state)
-            {
-                return Disposable.Empty;
-            }
-
-            public void Dispose()
-            {
-                _disposable.Dispose();
-            }
-        }
-
-        abstract class PeriodicTimer
-        {
-            //
-            // Note: the dictionary exists to "root" the timers so that they are not garbage collected and finalized while they are running.
-            //
-            protected static readonly HashSet<System.Threading.Timer> s_timers = new HashSet<System.Threading.Timer>();
-        }
-
-        sealed class PeriodicTimer<TState> : PeriodicTimer, IDisposable
-        {
-            private readonly AsyncLock _gate;
-
-            private TState _state;
-            private Func<TState, TState> _action;
-            private System.Threading.Timer _timer;
-
-            public PeriodicTimer(TState state, TimeSpan period, Func<TState, TState> action)
-            {
-                _gate = new AsyncLock();
-
-                _state = state;
-                _action = action;
-                _timer = new System.Threading.Timer(Tick, null, period, period);
-
-                lock (s_timers)
-                {
-                    s_timers.Add(_timer);
-                }
-            }
-
-            private void Tick(object state)
-            {
-                _gate.Wait(() =>
-                {
-                    _state = _action(_state);
-                });
-            }
-
-            public void Dispose()
-            {
-                var timer = default(System.Threading.Timer);
-
-                lock (s_timers)
-                {
-                    timer = _timer;
-                    _timer = null;
-
-                    if (timer != null)
-                        s_timers.Remove(timer);
-                }
-
-                if (timer != null)
-                {
-                    timer.Dispose();
-                    _gate.Dispose();
-                    _action = Stubs<TState>.I;
-                }
-            }
-        }
-#endif
     }
 }
 #endif