|
1 | 1 | using System;
|
2 |
| -using System.Collections.Concurrent; |
3 | 2 | using System.Collections.Generic;
|
4 | 3 | using System.Linq;
|
5 | 4 | using System.Threading;
|
@@ -288,25 +287,55 @@ public static ConnectionPool GetPool(ConnectionSettings cs)
|
288 | 287 |
|
289 | 288 | var key = cs.ConnectionString;
|
290 | 289 |
|
291 |
| - if (!s_pools.TryGetValue(key, out var pool)) |
| 290 | + try |
| 291 | + { |
| 292 | + s_poolLock.EnterReadLock(); |
| 293 | + if (s_pools.TryGetValue(key, out var pool)) |
| 294 | + return pool; |
| 295 | + } |
| 296 | + finally |
| 297 | + { |
| 298 | + s_poolLock.ExitReadLock(); |
| 299 | + } |
| 300 | + |
| 301 | + try |
| 302 | + { |
| 303 | + s_poolLock.EnterWriteLock(); |
| 304 | + if (!s_pools.TryGetValue(key, out var pool)) |
| 305 | + pool = s_pools[key] = new ConnectionPool(cs); |
| 306 | + return pool; |
| 307 | + } |
| 308 | + finally |
292 | 309 | {
|
293 |
| - pool = s_pools.GetOrAdd(cs.ConnectionString, newKey => new ConnectionPool(cs)); |
| 310 | + s_poolLock.ExitWriteLock(); |
294 | 311 | }
|
295 |
| - return pool; |
296 | 312 | }
|
297 | 313 |
|
298 | 314 | public static async Task ClearPoolsAsync(IOBehavior ioBehavior, CancellationToken cancellationToken)
|
299 | 315 | {
|
300 |
| - foreach (var pool in s_pools.Values) |
| 316 | + foreach (var pool in GetAllPools()) |
301 | 317 | await pool.ClearAsync(ioBehavior, cancellationToken).ConfigureAwait(false);
|
302 | 318 | }
|
303 | 319 |
|
304 | 320 | public static async Task ReapPoolsAsync(IOBehavior ioBehavior, CancellationToken cancellationToken)
|
305 | 321 | {
|
306 |
| - foreach (var pool in s_pools.Values) |
| 322 | + foreach (var pool in GetAllPools()) |
307 | 323 | await pool.ReapAsync(ioBehavior, cancellationToken).ConfigureAwait(false);
|
308 | 324 | }
|
309 | 325 |
|
| 326 | + private static IReadOnlyList<ConnectionPool> GetAllPools() |
| 327 | + { |
| 328 | + try |
| 329 | + { |
| 330 | + s_poolLock.EnterReadLock(); |
| 331 | + return s_pools.Values.ToList(); |
| 332 | + } |
| 333 | + finally |
| 334 | + { |
| 335 | + s_poolLock.ExitReadLock(); |
| 336 | + } |
| 337 | + } |
| 338 | + |
310 | 339 | private ConnectionPool(ConnectionSettings cs)
|
311 | 340 | {
|
312 | 341 | m_connectionSettings = cs;
|
@@ -350,7 +379,8 @@ public IEnumerable<string> LoadBalance(IReadOnlyList<string> hosts)
|
350 | 379 | readonly ConnectionPool m_pool;
|
351 | 380 | }
|
352 | 381 |
|
353 |
| - static readonly ConcurrentDictionary<string, ConnectionPool> s_pools = new ConcurrentDictionary<string, ConnectionPool>(); |
| 382 | + static readonly ReaderWriterLockSlim s_poolLock = new ReaderWriterLockSlim(); |
| 383 | + static readonly Dictionary<string, ConnectionPool> s_pools = new Dictionary<string, ConnectionPool>(); |
354 | 384 | #if DEBUG
|
355 | 385 | static readonly TimeSpan ReaperInterval = TimeSpan.FromSeconds(1);
|
356 | 386 | #else
|
|
0 commit comments