为什么此代码总是得到SynchronizationLockException

本文关键字:SynchronizationLockException 代码 为什么 | 更新日期: 2023-09-27 17:59:17

此代码有什么问题?

我总是收到

对象同步方法为从的未同步块调用代码

异常

System.Threading.Monitor.Exit(m_sqlConnection)

但是。。。不管我是把Monitor语句放在try-catch finally块的内部还是外部,在任何组合中,我总是会得到这个异常。

也就是说,在我编译了代码之后。如果我在得到第一个异常后让它再次运行,它会正常工作。。。它总是在重新编译之后。。。

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.Monitor.Exit(m_sqlConnection)
                daQueryTable.Dispose()
                daQueryTable = Nothing
            End Try
            Return dt.Rows.Count
        End Function ' GetDataTable

C#版本:

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

为什么此代码总是得到SynchronizationLockException

您正在调用TryEnter,但忽略结果-因此即使您不拥有它,也要尝试退出监视器。如果TryEnter返回false,您应该采取适当的操作,例如退出方法。

由于lock语句是Monitor.EnterMonitor.Exit的快捷方式,我建议您简单地使用lock语句并忽略Monitor类。