Microsoft.Data.SqlClient.ConnectionPool.ChannelDbConnectionPool
A connection pool implementation based on the channel data structure.
Provides methods to manage the pool of connections, including acquiring and releasing connections.
This implementation uses Channel<T> for managing idle connections,
which offers several advantages over the traditional WaitHandleDbConnectionPool:
Better async performance: Channels provide native async/await support without blocking
threads, unlike wait handles which can block managed threads and potentially cause thread pool starvation.
FIFO fairness: Channels guarantee first-come, first-served ordering for connection requests,
ensuring fair access to connections under high contention scenarios.
Reduced lock contention: The channel-based approach minimizes lock usage compared to
traditional synchronization primitives, improving scalability under concurrent load.
Simplified state management: Eliminates complex wait handle coordination and reduces
the potential for race conditions in connection lifecycle management.
The trade-off is slightly higher memory overhead per pool instance due to the channel infrastructure,
but this is generally offset by the performance benefits in async-heavy workloads.
namespace Microsoft.Data.SqlClient.ConnectionPool
{
internal sealed class ChannelDbConnectionPool : IDbConnectionPool
{
public ConcurrentDictionary<DbConnectionPoolAuthenticationContextKey, DbConnectionPoolAuthenticationContext> AuthenticationContexts { get; }
public SqlConnectionFactory ConnectionFactory { get; }
public int Count { get; }
public int IdleCount { get; }
public bool ErrorOccurred { get; }
public int Id { get; }
public DbConnectionPoolIdentity Identity { get; }
public bool IsRunning { get; }
public TimeSpan LoadBalanceTimeout { get; }
public DbConnectionPoolGroup PoolGroup { get; }
public DbConnectionPoolGroupOptions PoolGroupOptions { get; }
public DbConnectionPoolProviderInfo ProviderInfo { get; }
public DbConnectionPoolState State { get; }
public TransactedConnectionPool TransactedConnectionPool { get; }
public bool UseLoadBalancing { get; }
public void Clear();
public void PutObjectFromTransactedPool(DbConnectionInternal connection);
public DbConnectionInternal ReplaceConnection(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection);
public void ReturnInternalConnection(DbConnectionInternal connection, DbConnection owningObject);
public void Shutdown();
public void Startup();
public void TransactionEnded(Transaction transaction, DbConnectionInternal transactedObject);
public bool TryGetConnection(DbConnection owningObject, TaskCompletionSource<DbConnectionInternal> taskCompletionSource, DbConnectionOptions userOptions, out DbConnectionInternal connection);
}
}