I have a .net DLL which calls a c++ DLL which is not thread safe. The .NET DLL is run in IIS. IIS application pool loads a single copy of both DLLs and when two browsers sessions calls the .NET DLL at the same time the c++ DLL Ralph's on its shoes. In certain cases it will cause the application pool to fail in others I get a trappable error.
I attempted to use the Monitor Class to solve my problem like;
    Private objSync As Object = New Object
.
.
.
.
        Monitor.Enter(objSync)
        editsErrorHandler(MycPlusPlusCall(_intsmfID, _strEditSetTag, _strEditLayoutTag, strNAACCRRecord,
                                            EE_SKIPFAIL, intErrCount, _ptrThis, _ptrEditsMessagerHandler),
                                           "MycPlusPlusCall")
        objMessageTransport.intMstErrorCount = intErrCount
        objMessageTransport.objMstMessages = _objErrorMessages
        '        Debug.Print("intErrCount=" & intErrCount)
        Monitor.Exit(objSync)
MycPlusPlusCall is the c++ DLL call.
This seemed to have no impact.
This is my first foray into calling non thread safe DLLs.
How can I force multiple calls from the application pool to wait until the previous call finishes?
Edit:
I moved the Monitor up one level and have succeeded in getting W3WP to crash almost every time. When it crashes I get AppCrash on w3wp with the module being the c++ DLL.
The .NET DLL referenced above is called by a DLL "above" it so I moved the Monitor.Enter & Exit to that level. The new & improved code looks like;
    Private Function processRecord(ByVal strInterRecordEditsName As String, _
                                   ByVal objConnection As OracleConnection) As Integer
        Dim strNAACCRRecord As String = buildNAACCRRecord(_objRecord)
        '           Dim strNAACCRRecord As String = _objRecord("NAACCR_RECORD")
        Dim objErrorMessageTransport As ACEEdits50.EditMessageTransport
        Dim intErrCount As Integer = 0
        Dim objErrorMessages As List(Of ACEEdits50.EditMessage) = New List(Of ACEEdits50.EditMessage)
        Dim strDebug As String = "Section 10"
        On Error GoTo processRecordError
        Monitor.Enter(_objACEEdits)
        ' Here is where the heavy lifting is done.
        objErrorMessageTransport = _objACEEdits.runEdits(strNAACCRRecord & Space(_intNAACCRRecordSize - strNAACCRRecord.Length))
        Monitor.Exit(_objACEEdits)
Edit 2:
So I removed the higher "Monitor.Enter/Exit" and replaced it with SyncLock as recommended below, with the added option of making the object "private shared" So the code looks like;
Public Class ACEEdits50
    Public Sub New()
    End Sub
.
.
.
.
    Private Shared objSync As Object = New Object
.
.
.
.
    Public Function runEdits(ByVal strNAACCRRecord As String) As EditMessageTransport
.
.
.
.
        SyncLock objSync
            editsErrorHandler(Edit_RunEdits(_intsmfID, _strEditSetTag, _strEditLayoutTag, strNAACCRRecord,
                                                EE_SKIPFAIL, intErrCount, _ptrThis, _ptrEditsMessagerHandler),
                                               "Edit_RunEdits")
            objMessageTransport.intMstErrorCount = intErrCount
            objMessageTransport.objMstMessages = _objErrorMessages
            '        Debug.Print("intErrCount=" & intErrCount)
        End SyncLock
I still get the same appCrash.