Hello
I'm sort off new to C#/.net 2.0, so I would like some input on a SocketPool class I've build.
The concept is the same as the one behind .net's ThreadPool class. My application only uses a socket for a short time (roughly 0.5 sec), but uses many, so I want to reuse sockets instead of creating new ones every time I need one (to save the time it takes to create one, and the time the garbage collector will use cleaning up).
A few questions for my code:
-
I'm unsure if the garbage collector will terminate some of the sockets if they haven't been used for a period of time, even though they are referenced in a static Queue.
-
I've done my best to make it fast, but there is probably room for improvements, idea's are much welcome.
-
I've also done my best to make it thread safe, but again, my limited knowledge of C#/.net thread programming might not have been enough. Any input on this subject is much welcome as well.
Any other comments are welcome as well of course, here's my code:
static class SocketPool {
#region Private variables.
private const short numOfSockets = 25;
private const int socketTimeOut = 8000;
private static AutoResetEvent socketAvailableEvent = new AutoResetEvent(false);
private static SortedDictionary<int, Socket> socketsInUse = new SortedDictionary<int,Socket>();
private static Queue<Socket> availableSockets = new Queue<Socket>(numOfSockets);
#endregion
#region Static constructor
static SocketPool() {
// Build the socket pool.
Socket socket;
for(short i = 0; i < numOfSockets; i++) {
socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, socketTimeOut);
availableSockets.Enqueue(socket);
}
}
#endregion
#region Public methods
public static void getSocket(out Socket socket) {
// Are there any available sockets
while (availableSockets.Count <= 0) {
// If not, wait untill one is.
socketAvailableEvent.WaitOne();
}
// Take the first available socket.
lock(availableSockets) {
socket = availableSockets.Dequeue();
}
lock(socketsInUse) {
socketsInUse.Add(socket.GetHashCode(), socket);
}
}
public static void releaseSocket(ref Socket socket) {
// Is the socket indeed in use
int socketHash = socket.GetHashCode();
if(socketsInUse.ContainsKey(socketHash)) {
// Mark socket as available.
lock(socketsInUse) {
socketsInUse.Remove(socketHash);
}
lock(availableSockets) {
availableSockets.Enqueue(socket);
}
// Signal possible waiting thread that a socket is now available.
socketAvailableEvent.Set();
}
}
#endregion
}

Input/comments on my SocketPool class