Why does this code always get a SynchronizationLockException?
What's wrong with this code ?
I always get a
Object synchronization method was called from an unsynchronized block of code
Exception on
System.Threading.Monitor.Exit(m_sqlConnection)
But... It doesn't matter whether I put the Monitor statement inside or outside the try-catch-finally-block, in any combination, I always get this exception.
That is, after I compiled the code. If I let it run again after getting the first exception, it works fine... It's always after recompilation...
Public Shared Function GetDataTable(ByRef strSQL As String, ByRef dt As System.Data.DataTable, Optional ByRef strTableName As String = "ThisTable") As Integer
Dim daQueryTable As System.Data.SqlClient.SqlDataAdapter = Nothing
Try
System.Threading.Monitor.TryEnter(m_sqlConnection, 5000)
If isDataBaseConnectionOpen() = False Then OpenSQLConnection()
daQueryTable = New System.Data.SqlClient.SqlDataAdapter(strSQL, m_sqlConnection)
dt = New System.Data.DataTable(strTableName)
daQueryTable.Fill(dt)
Catch ex As Exception
Log(ex)
Return -1
Finally
m_sqlConnection.Close()
System.Threading.M开发者_JS百科onitor.Exit(m_sqlConnection)
daQueryTable.Dispose()
daQueryTable = Nothing
End Try
Return dt.Rows.Count
End Function ' GetDataTable
C# version:
public static int GetDataTable(ref string strSQL, ref System.Data.DataTable dt, ref string strTableName = "ThisTable")
{
System.Data.SqlClient.SqlDataAdapter daQueryTable = null;
try {
System.Threading.Monitor.TryEnter(m_sqlConnection, 5000);
if (isDataBaseConnectionOpen() == false)
OpenSQLConnection();
daQueryTable = new System.Data.SqlClient.SqlDataAdapter(strSQL, m_sqlConnection);
dt = new System.Data.DataTable(strTableName);
daQueryTable.Fill(dt);
} catch (Exception ex) {
Log(ex);
return -1;
} finally {
m_sqlConnection.Close();
System.Threading.Monitor.Exit(m_sqlConnection);
daQueryTable.Dispose();
daQueryTable = null;
}
return dt.Rows.Count;
} // GetDataTable
You're calling TryEnter
, but ignoring the result - so you're going to try to exit the monitor even if you don't own it. You should take appropriate action if TryEnter
returns false, such as exiting the method.
Since the lock
statement is a shortcut for Monitor.Enter
and Monitor.Exit
, I would recommend that you simple use the lock
statement and ignore the Monitor
classes.
精彩评论