I'm building a slightly more efficient connection pool for a multi threaded service I'm writing to talk between my service and its SQL database. basically boiled down, I've got this code in my class:
Public Class DBMC
Private Connections As New ArrayList
Private Function GetConnection() As Object
Dim conCounter As Integer = 0
While True
If Connections.Count > conCounter Then
If System.Threading.Monitor.TryEnter(Connections(conCounter), 10) Then
Return Connections(conCounter)
Else
conCounter += 1
End If
ElseIf conCounter > 98 Then
'keep looping until an open connection is found
conCounter = 0
ElseIf conCounter < 98 Then
Dim connection As Object = NewCon()
If connection Is Nothing Then
conCounter = 0
Else
Connections.Add(connection)
Return connection
End If
End If
End While
'below line should never run
Return Nothing
End Function
Public Function DBSelect(ByVal SQL As String) As DataSet
Dim connection As Object = GetConnection()
SyncLock (connection)
'Run the select vs database and do a bunch of other stuff
End SyncLock
Try
System.Threading.Monitor.Exit(connection)
Catch ex As Exception
End Try
Return DataSet
End Function
End Class
So this code works absolutely great, I can run 500 select statements in different threads as fast as the computer can make them and it will open 8 different connections (likely due to the speed of my computer, a slower PC may open more). The thing is, in the DBSelect function, I have a line surrounded in Try/Catch to release the monitor Enter because sometimes ending the synclock drops the locks on my objects (in this case the line is not needed and throws an exception) and sometimes the object is still locked and would stay permanently locked without running that line (in which case it uses it and passes successfully). I cannot figure out for the life of me why Sometimes it releases it, and sometimes it doesn't. Any ideas?