Skip to content

Commit e9bad6c

Browse files
committed
Suppress ExecutionContext while creating timers
1 parent 7320260 commit e9bad6c

4 files changed

Lines changed: 14 additions & 6 deletions

File tree

src/Npgsql/Internal/NpgsqlConnector.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,10 @@ internal NpgsqlConnector(NpgsqlDataSource dataSource, NpgsqlConnection conn)
398398

399399
_isKeepAliveEnabled = Settings.KeepAlive > 0;
400400
if (_isKeepAliveEnabled)
401-
_keepAliveTimer = new Timer(PerformKeepAlive, null, Timeout.Infinite, Timeout.Infinite);
401+
{
402+
using (ExecutionContext.SuppressFlow()) // Don't capture the current ExecutionContext and its AsyncLocals onto the timer causing them to live forever
403+
_keepAliveTimer = new Timer(PerformKeepAlive, null, Timeout.Infinite, Timeout.Infinite);
404+
}
402405

403406
DataReader = new NpgsqlDataReader(this);
404407

src/Npgsql/NpgsqlDataSource.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,9 @@ internal NpgsqlDataSource(
124124

125125
_timerPasswordProviderCancellationTokenSource = new();
126126

127-
// Create the timer, but don't start it; the manual run below will will schedule the first refresh.
128-
_periodicPasswordProviderTimer = new Timer(state => _ = RefreshPassword(), null, Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);
127+
// Create the timer, but don't start it; the manual run below will schedule the first refresh.
128+
using (ExecutionContext.SuppressFlow()) // Don't capture the current ExecutionContext and its AsyncLocals onto the timer causing them to live forever
129+
_periodicPasswordProviderTimer = new Timer(state => _ = RefreshPassword(), null, Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);
129130
// Trigger the first refresh attempt right now, outside the timer; this allows us to capture the Task so it can be observed
130131
// in GetPasswordAsync.
131132
_passwordRefreshTask = Task.Run(RefreshPassword);

src/Npgsql/PoolingDataSource.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ internal PoolingDataSource(
9797
if (connectionIdleLifetime < pruningSamplingInterval)
9898
throw new ArgumentException($"Connection can't have {nameof(settings.ConnectionIdleLifetime)} {connectionIdleLifetime} under {nameof(settings.ConnectionPruningInterval)} {pruningSamplingInterval}");
9999

100-
_pruningTimer = new Timer(PruningTimerCallback, this, Timeout.Infinite, Timeout.Infinite);
100+
using (ExecutionContext.SuppressFlow()) // Don't capture the current ExecutionContext and its AsyncLocals onto the timer causing them to live forever
101+
_pruningTimer = new Timer(PruningTimerCallback, this, Timeout.Infinite, Timeout.Infinite);
101102
_pruningSampleSize = DivideRoundingUp(settings.ConnectionIdleLifetime, settings.ConnectionPruningInterval);
102103
_pruningMedianIndex = DivideRoundingUp(_pruningSampleSize, 2) - 1; // - 1 to go from length to index
103104
_pruningSamplingInterval = pruningSamplingInterval;

src/Npgsql/Replication/ReplicationConnection.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -452,8 +452,11 @@ internal async IAsyncEnumerator<XLogDataMessage> StartReplicationInternal(
452452

453453
SetTimeouts(_walReceiverTimeout, CommandTimeout);
454454

455-
_sendFeedbackTimer = new Timer(TimerSendFeedback, state: null, WalReceiverStatusInterval, Timeout.InfiniteTimeSpan);
456-
_requestFeedbackTimer = new Timer(TimerRequestFeedback, state: null, _requestFeedbackInterval, Timeout.InfiniteTimeSpan);
455+
using (ExecutionContext.SuppressFlow()) // Don't capture the current ExecutionContext and its AsyncLocals onto the timer causing them to live forever
456+
{
457+
_sendFeedbackTimer = new Timer(TimerSendFeedback, state: null, WalReceiverStatusInterval, Timeout.InfiniteTimeSpan);
458+
_requestFeedbackTimer = new Timer(TimerRequestFeedback, state: null, _requestFeedbackInterval, Timeout.InfiniteTimeSpan);
459+
}
457460

458461
while (true)
459462
{

0 commit comments

Comments
 (0)