<PackageReference Include="Microsoft.Data.SqlClient" Version="7.1.0-preview2.26190.5" />

Microsoft.Data.SqlClient.ConnectionPool.WaitHandleDbConnectionPool

A concrete implementation of IDbConnectionPool used by Microsoft.Data.SqlClient to efficiently manage a pool of reusable DbConnectionInternal objects backing ADO.NET SqlConnection instances.

Primary Responsibilities:

Connection Reuse and Pooling: Uses two stacks (_stackNew and _stackOld) to manage idle connections. Ensures efficient reuse and limits new connection creation.Transaction-Aware Pooling: Tracks connections enlisted in Transaction using TransactedConnectionPool and TransactedConnectionList, ensuring proper context reuse.Concurrency and Synchronization: Uses wait handles and semaphores via PoolWaitHandles to coordinate safe multi-threaded access.Connection Lifecycle Management: Manages creation (CreateObject), deactivation (DeactivateObject), destruction (DestroyObject), and reclamation (ReclaimEmancipatedObjects) of internal connections.Error Handling and Resilience: Implements retry and exponential backoff in TryGetConnection and handles transient errors using _errorWait.Minimum Pool Size Enforcement: Maintains the MinPoolSize by spawning background tasks to create new connections when needed.Load Balancing Support: Honors LoadBalanceTimeout to clean up idle connections and distribute load evenly.Telemetry and Tracing: Uses SqlClientEventSource for extensive diagnostic tracing of connection lifecycle events.Pending Request Queue: Queues unresolved connection requests in _pendingOpens and processes them using background threads.Identity and Authentication Context: Manages identity-based reuse via a dictionary of DbConnectionPoolAuthenticationContext keyed by user identity.

Key Concepts in Design:

Stacks and queues for free and pending connectionsSynchronization via WaitHandle, Semaphore, and ManualResetEventSupport for transaction enlistment and affinityTimer-based cleanup to prune idle or expired connectionsBackground thread spawning for servicing deferred requests and replenishing the pool
namespace Microsoft.Data.SqlClient.ConnectionPool { internal sealed class WaitHandleDbConnectionPool : IDbConnectionPool { public int Id { get; } public DbConnectionPoolState State { get; set; } public int Count { get; } public int IdleCount { get; } public SqlConnectionFactory ConnectionFactory { get; } public bool ErrorOccurred { get; } public TimeSpan LoadBalanceTimeout { get; } public DbConnectionPoolIdentity Identity { get; } public bool IsRunning { get; } public DbConnectionPoolGroup PoolGroup { get; } public DbConnectionPoolGroupOptions PoolGroupOptions { get; } public DbConnectionPoolProviderInfo ProviderInfo { get; } public ConcurrentDictionary<DbConnectionPoolAuthenticationContextKey, DbConnectionPoolAuthenticationContext> AuthenticationContexts { get; } public bool UseLoadBalancing { get; } public TransactedConnectionPool TransactedConnectionPool { get; } public void Clear(); public bool TryGetConnection(DbConnection owningObject, TaskCompletionSource<DbConnectionInternal> taskCompletionSource, TimeoutTimer timeout, out DbConnectionInternal connection); public DbConnectionInternal ReplaceConnection(DbConnection owningObject, DbConnectionInternal oldConnection, TimeoutTimer timeout); public void ReturnInternalConnection(DbConnectionInternal obj, DbConnection owningObject); public void PutObjectFromTransactedPool(DbConnectionInternal obj); public void Startup(); public void Shutdown(); public void TransactionEnded(Transaction transaction, DbConnectionInternal transactedObject); } }