Skip to content

Commit

Permalink
ConcurrencyAbstractionLayerImpl.Timer: Allow delegate caching.
Browse files Browse the repository at this point in the history
  • Loading branch information
danielcweber committed May 28, 2018
1 parent 47ef6fc commit e092e03
Showing 1 changed file with 11 additions and 6 deletions.
Expand Up @@ -132,35 +132,39 @@ public void StartThread(Action<object> action, object state)

private sealed class Timer : IDisposable
{
private object _state;
private Action<object> _action;
private volatile System.Threading.Timer _timer;

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 this.Tick delegate's target object,
// 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, state, dueTime, TimeSpan.FromMilliseconds(System.Threading.Timeout.Infinite));
_timer = new System.Threading.Timer(_ => Tick(_), this, dueTime, TimeSpan.FromMilliseconds(System.Threading.Timeout.Infinite));
}
}

private void Tick(object state)
private static void Tick(object state)
{
var timer = (Timer) state;

try
{
_action(state);
timer._action(timer._state);
}
finally
{
SpinWait.SpinUntil(IsTimerAssigned);
Dispose();
SpinWait.SpinUntil(timer.IsTimerAssigned);
timer.Dispose();
}
}

Expand All @@ -173,6 +177,7 @@ public void Dispose()
{
_action = Stubs<object>.Ignore;
_timer = TimerStubs.Never;
_state = null;

timer.Dispose();
}
Expand Down

0 comments on commit e092e03

Please sign in to comment.