Don't capture AsyncLocals onto Timers (#2904)

This commit is contained in:
Ben Adams 2018-09-07 22:08:08 +01:00 committed by Andrew Stanton-Nurse
parent b9e118b61f
commit db99baac35
2 changed files with 40 additions and 2 deletions

View File

@ -40,7 +40,26 @@ namespace Microsoft.AspNetCore.Internal
if (_timer == null)
{
_timer = new Timer(state => ((TimerAwaitable)state).Tick(), this, _dueTime, _period);
// Don't capture the current ExecutionContext and its AsyncLocals onto the timer
bool restoreFlow = false;
try
{
if (!ExecutionContext.IsFlowSuppressed())
{
ExecutionContext.SuppressFlow();
restoreFlow = true;
}
_timer = new Timer(state => ((TimerAwaitable)state).Tick(), this, _dueTime, _period);
}
finally
{
// Restore the current ExecutionContext
if (restoreFlow)
{
ExecutionContext.RestoreFlow();
}
}
}
}
}

View File

@ -19,7 +19,26 @@ namespace Microsoft.AspNetCore.SignalR.Redis.Internal
public AckHandler()
{
_timer = new Timer(_ => CheckAcks(), state: null, dueTime: _ackInterval, period: _ackInterval);
// Don't capture the current ExecutionContext and its AsyncLocals onto the timer
bool restoreFlow = false;
try
{
if (!ExecutionContext.IsFlowSuppressed())
{
ExecutionContext.SuppressFlow();
restoreFlow = true;
}
_timer = new Timer(state => ((AckHandler)state).CheckAcks(), state: this, dueTime: _ackInterval, period: _ackInterval);
}
finally
{
// Restore the current ExecutionContext
if (restoreFlow)
{
ExecutionContext.RestoreFlow();
}
}
}
public Task CreateAck(int id)