PooledConnections.cs 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. using System.Collections.Concurrent;
  2. using System.Threading.Tasks;
  3. namespace appMpower.Db
  4. {
  5. public static class PooledConnections
  6. {
  7. private static bool _connectionsCreated = false;
  8. private static short _createdConnections = 0;
  9. private static short _maxConnections = 240;
  10. private static ConcurrentStack<PooledConnection> _stack = new ConcurrentStack<PooledConnection>();
  11. private static ConcurrentQueue<TaskCompletionSource<PooledConnection>> _waitingQueue = new ConcurrentQueue<TaskCompletionSource<PooledConnection>>();
  12. public static async Task<PooledConnection> GetConnection(string connectionString)
  13. {
  14. PooledConnection pooledConnection = null;
  15. if (_connectionsCreated)
  16. {
  17. if (_stack.TryPop(out pooledConnection))
  18. {
  19. pooledConnection.Released = false;
  20. }
  21. else
  22. {
  23. pooledConnection = await GetPooledConnectionAsync();
  24. }
  25. return pooledConnection;
  26. }
  27. else
  28. {
  29. pooledConnection = new PooledConnection();
  30. #if ADO
  31. pooledConnection.DbConnection = new Npgsql.NpgsqlConnection(connectionString);
  32. #else
  33. pooledConnection.DbConnection = new System.Data.Odbc.OdbcConnection(connectionString);
  34. #endif
  35. _createdConnections++;
  36. if (_createdConnections == _maxConnections) _connectionsCreated = true;
  37. pooledConnection.Number = _createdConnections;
  38. pooledConnection.PooledCommands = new ConcurrentDictionary<string, PooledCommand>();
  39. //Console.WriteLine("opened connection number: " + pooledConnection.Number);
  40. return pooledConnection;
  41. }
  42. }
  43. public static Task<PooledConnection> GetPooledConnectionAsync()
  44. {
  45. var taskCompletionSource = new TaskCompletionSource<PooledConnection>(TaskCreationOptions.RunContinuationsAsynchronously);
  46. _waitingQueue.Enqueue(taskCompletionSource);
  47. return taskCompletionSource.Task;
  48. }
  49. public static void Dispose(PooledConnection pooledConnection)
  50. {
  51. PooledConnection newPooledConnection = new PooledConnection();
  52. newPooledConnection.DbConnection = pooledConnection.DbConnection;
  53. newPooledConnection.Number = pooledConnection.Number;
  54. newPooledConnection.PooledCommands = pooledConnection.PooledCommands;
  55. Release(newPooledConnection);
  56. }
  57. public static void Release(PooledConnection pooledConnection)
  58. {
  59. TaskCompletionSource<PooledConnection> taskCompletionSource;
  60. if (_waitingQueue.TryDequeue(out taskCompletionSource))
  61. {
  62. taskCompletionSource.SetResult(pooledConnection);
  63. }
  64. else
  65. {
  66. pooledConnection.Released = true;
  67. _stack.Push(pooledConnection);
  68. }
  69. }
  70. }
  71. }