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.