我正在为我正在编写的多线程服务构建一个稍微更有效的连接池,以便在我的服务和它的 SQL 数据库之间进行通信。基本上归结为,我的课堂上有这段代码:
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
所以这段代码工作得非常好,我可以在不同的线程中运行 500 条 select 语句,就像计算机可以使它们一样快,它会打开 8 个不同的连接(可能是由于我的计算机的速度,较慢的 PC 可能会打开更多)。问题是,在 DBSelect 函数中,我在 Try/Catch 中有一行用于释放监视器 Enter 因为有时结束同步锁会丢弃我的对象上的锁(在这种情况下,不需要该行并引发异常),有时该对象仍处于锁定状态,并且将在不运行该行的情况下保持永久锁定(在这种情况下,它会使用它并成功通过)。我无法弄清楚为什么有时它会释放它,有时它不会。有任何想法吗?