added samples
[windows-sources.git] / sdk / samples / WCFSamples / TechnologySamples / Extensibility / Instancing / Pooling / CS / extensions / ObjectPoolInstanceProvider.cs
blobf89cfc03c7ff157d17feb02a6e110a09e625d766
1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4 using System.Reflection;
5 using System.ServiceModel;
6 using System.ServiceModel.Channels;
7 using System.ServiceModel.Dispatcher;
8 using System.Threading;
9 using System.Timers;
10 using Timer = System.Timers.Timer;
12 namespace Microsoft.ServiceModel.Samples
14 // This class contains the implementation for the object pool. This implements the
15 // IInstanceProvider interface in order to be able to plugin to the dispatcher layer.
16 class ObjectPoolingInstanceProvider : IInstanceProvider
18 const int idleTimeout = 5 * 60 * 1000; // 5 minutes
20 #region Private Fields
22 // Minimum number of objects in the pool
23 int minPoolSize;
25 // Type of the object created in the pool
26 Type instanceType;
28 // Stack used for storing objects in the pool
29 Stack<object> pool;
31 // Lock should acquired before accessing the pool stack
32 object poolLock = new object();
34 // Keeps track of the number of objects returned from the pool.
35 int activeObjectsCount;
37 // Timer object used to trigger the clean up process
38 // after a given period of idle time.
39 Timer idleTimer;
41 #endregion
43 public ObjectPoolingInstanceProvider(Type instanceType, int minPoolSize)
45 this.minPoolSize = minPoolSize;
46 this.instanceType = instanceType;
48 pool = new Stack<object>();
49 activeObjectsCount = 0;
51 // Initialize the timer and subscribe to the "Elapsed" event
52 idleTimer = new Timer(idleTimeout);
53 idleTimer.Elapsed += new System.Timers.ElapsedEventHandler(idleTimer_Elapsed);
55 // Initialize the minimum number of objects if possible
56 Initialize();
59 #region IInstanceProvider Members
61 object IInstanceProvider.GetInstance(InstanceContext instanceContext)
63 return ((IInstanceProvider)this).GetInstance(instanceContext, null);
66 object IInstanceProvider.GetInstance(InstanceContext instanceContext, Message message)
68 object obj = null;
70 lock (poolLock)
72 if (pool.Count > 0)
74 obj = pool.Pop();
76 else
78 obj = CreateNewPoolObject();
80 activeObjectsCount++;
83 WritePoolMessage(ResourceHelper.GetString("MsgNewObject"));
85 idleTimer.Stop();
87 return obj;
90 void IInstanceProvider.ReleaseInstance(InstanceContext instanceContext, object instance)
92 lock (poolLock)
94 pool.Push(instance);
95 activeObjectsCount--;
97 WritePoolMessage(ResourceHelper.GetString("MsgObjectPooled"));
99 // When the service goes completely idle (no requests are being processed),
100 // the idle timer is started
101 if (activeObjectsCount == 0)
102 idleTimer.Start();
106 #endregion
108 // Initialize the pool with minimum number of instances
109 void Initialize()
111 for (int i = 0; i < minPoolSize; i++)
113 pool.Push(CreateNewPoolObject());
117 // Handles the instantiation of the types created by this instance
118 private object CreateNewPoolObject()
120 return Activator.CreateInstance(instanceType);
123 // Clean up procedure
124 void idleTimer_Elapsed(object sender, ElapsedEventArgs args)
126 idleTimer.Stop();
128 lock (poolLock)
130 if (activeObjectsCount == 0)
132 while (pool.Count > minPoolSize)
134 WritePoolMessage(ResourceHelper.GetString("MsgObjectRemoving"));
136 object removedItem = pool.Pop();
138 if (removedItem is IDisposable)
140 ((IDisposable)removedItem).Dispose();
147 // Writes a given message to the console in red color
148 void WritePoolMessage(string message)
150 ConsoleColor currentForegroundColor = Console.ForegroundColor;
151 Console.ForegroundColor = ConsoleColor.Red;
152 Console.WriteLine(message);
153 Console.ForegroundColor = currentForegroundColor;