|
|
@@ -152,25 +152,18 @@ namespace System.Reactive.Concurrency
|
|
|
|
|
|
private sealed class Timer : IDisposable
|
|
|
{
|
|
|
- private object _state;
|
|
|
+ private volatile object _state;
|
|
|
private Action<object> _action;
|
|
|
- private volatile System.Threading.Timer _timer;
|
|
|
+ private IDisposable _timer;
|
|
|
+
|
|
|
+ private static readonly object DisposedState = new object();
|
|
|
|
|
|
public Timer(Action<object> action, object state, TimeSpan dueTime)
|
|
|
{
|
|
|
_state = state;
|
|
|
_action = action;
|
|
|
|
|
|
- // Don't want the spin wait in Tick to get stuck if this thread gets aborted.
|
|
|
- try { }
|
|
|
- finally
|
|
|
- {
|
|
|
- //
|
|
|
- // Rooting of the timer happens through the Timer's state
|
|
|
- // which is the current instance and has a field to store the Timer instance.
|
|
|
- //
|
|
|
- _timer = new System.Threading.Timer(_ => Tick(_), this, dueTime, TimeSpan.FromMilliseconds(System.Threading.Timeout.Infinite));
|
|
|
- }
|
|
|
+ Disposable.SetSingle(ref _timer, new System.Threading.Timer(_ => Tick(_), this, dueTime, TimeSpan.FromMilliseconds(System.Threading.Timeout.Infinite)));
|
|
|
}
|
|
|
|
|
|
private static void Tick(object state)
|
|
|
@@ -179,27 +172,24 @@ namespace System.Reactive.Concurrency
|
|
|
|
|
|
try
|
|
|
{
|
|
|
- timer._action(timer._state);
|
|
|
+ var timerState = timer._state;
|
|
|
+ if (timerState != DisposedState)
|
|
|
+ {
|
|
|
+ timer._action(timerState);
|
|
|
+ }
|
|
|
}
|
|
|
finally
|
|
|
{
|
|
|
- SpinWait.SpinUntil(timer.IsTimerAssigned);
|
|
|
- timer.Dispose();
|
|
|
+ Disposable.TryDispose(ref timer._timer);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private bool IsTimerAssigned() => _timer != null;
|
|
|
-
|
|
|
public void Dispose()
|
|
|
{
|
|
|
- var timer = _timer;
|
|
|
- if (timer != TimerStubs.Never)
|
|
|
+ if (Disposable.TryDispose(ref _timer))
|
|
|
{
|
|
|
_action = Stubs<object>.Ignore;
|
|
|
- _timer = TimerStubs.Never;
|
|
|
- _state = null;
|
|
|
-
|
|
|
- timer.Dispose();
|
|
|
+ _state = DisposedState;
|
|
|
}
|
|
|
}
|
|
|
}
|