1 namespaceObjectPoolPattern.Implementation12 {3 public abstract class ObjectPool
4 {5 privateTimeSpan _expirationTime;6 private Dictionary_unlocked;7 private Dictionary_locked;8 private readonly object _sync = new object();9
10 publicObjectPool()11 {12 _expirationTime = TimeSpan.FromSeconds(30);13 _locked = new Dictionary();14 _unlocked = new Dictionary();15 }16
17 publicObjectPool(TimeSpan expirationTime)18 : this()19 {20 _expirationTime =expirationTime;21 }22
23 protected abstractT Create();24
25 public abstract boolValidate(T reusable);26
27 public abstract voidExpire(T reusable);28
29 publicT CheckOut()30 {31 lock(_sync)32 {33 T reusable = default(T);34
35 if (_unlocked.Count > 0)36 {37 foreach (var item in_unlocked)38 {39 if ((DateTime.UtcNow - item.Value) >_expirationTime)40 {41 //object has expired
42 _unlocked.Remove(item.Key);43 Expire(item.Key);44 }45 else
46 {47 if(Validate(item.Key))48 {49 //find a reusable object
50 _unlocked.Remove(item.Key);51 _locked.Add(item.Key, DateTime.UtcNow);52 reusable =item.Key;53 break;54 }55 else
56 {57 //object failed validation
58 _unlocked.Remove(item.Key);59 Expire(item.Key);60 }61 }62 }63 }64
65 //no object available, create a new one
66 if (reusable == null)67 {68 reusable =Create();69 _locked.Add(reusable, DateTime.UtcNow);70 }71
72 returnreusable;73 }74 }75
76 public voidCheckIn(T reusable)77 {78 lock(_sync)79 {80 _locked.Remove(reusable);81 _unlocked.Add(reusable, DateTime.UtcNow);82 }83 }84 }85
86 public classDatabaseConnection : IDisposable87 {88 //do some heavy works
89 public DatabaseConnection(stringconnectionString)90 {91 }92
93 public bool IsOpen { get; set; }94
95 //release something
96 public voidDispose()97 {98 }99 }100
101 public class DatabaseConnectionPool : ObjectPool
102 {103 private string_connectionString;104
105 public DatabaseConnectionPool(stringconnectionString)106 : base(TimeSpan.FromMinutes(1))107 {108 this._connectionString =connectionString;109 }110
111 protected overrideDatabaseConnection Create()112 {113 return newDatabaseConnection(_connectionString);114 }115
116 public override voidExpire(DatabaseConnection connection)117 {118 connection.Dispose();119 }120
121 public override boolValidate(DatabaseConnection connection)122 {123 returnconnection.IsOpen;124 }125 }126
127 public classClient128 {129 public static voidTestCase1()130 {131 //Create the ConnectionPool:
132 DatabaseConnectionPool pool = newDatabaseConnectionPool(133 "Data Source=DENNIS;Initial Catalog=TESTDB;Integrated Security=True;");134
135 //Get a connection:
136 DatabaseConnection connection =pool.CheckOut();137
138 //Use the connection139
140 //Return the connection:
141 pool.CheckIn(connection);142 }143 }144 }