Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.Monitor.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
like image 725
Stefan Steiger Avatar asked Jun 17 '11 07:06

Stefan Steiger


1 Answers

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.

like image 73
Jon Skeet Avatar answered Nov 08 '22 09:11

Jon Skeet