|  | @@ -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
 |