开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜