Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在.NET中,如何保护一段代码不同时执行两次 我有一个.NET DLL,它调用一个不是线程安全的C++ DLL。.NET DLL在IIS中运行。IIS应用程序池加载DLL的单个副本,当两个浏览器会话同时调用.NdDLL时,其上的C++ DLL拉尔夫就在其上。在某些情况下,它会导致应用程序池失败,在其他情况下,我会得到一个可捕获的错误_.net_Vb.net - Fatal编程技术网

在.NET中,如何保护一段代码不同时执行两次 我有一个.NET DLL,它调用一个不是线程安全的C++ DLL。.NET DLL在IIS中运行。IIS应用程序池加载DLL的单个副本,当两个浏览器会话同时调用.NdDLL时,其上的C++ DLL拉尔夫就在其上。在某些情况下,它会导致应用程序池失败,在其他情况下,我会得到一个可捕获的错误

在.NET中,如何保护一段代码不同时执行两次 我有一个.NET DLL,它调用一个不是线程安全的C++ DLL。.NET DLL在IIS中运行。IIS应用程序池加载DLL的单个副本,当两个浏览器会话同时调用.NdDLL时,其上的C++ DLL拉尔夫就在其上。在某些情况下,它会导致应用程序池失败,在其他情况下,我会得到一个可捕获的错误,.net,vb.net,.net,Vb.net,我尝试使用Monitor类来解决我的问题,如: Private objSync As Object = New Object . . . . Monitor.Enter(objSync) editsErrorHandler(MycPlusPlusCall(_intsmfID, _strEditSetTag, _strEditLayoutTag, strNAACCRRecord,

我尝试使用Monitor类来解决我的问题,如:

    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)

MycPulsPulsCalk是C++ DLL调用。< /P> 这似乎没有影响

这是我第一次尝试调用非线程安全DLL

如何强制应用程序池中的多个调用等待上一个调用完成

编辑:

我将显示器向上移动了一级,并成功地使W3WP几乎每次都崩溃。当崩溃时,我在W3WP上得到崩溃,模块是C++ DLL。 上面引用的.NET DLL是由“上面”的DLL调用的,因此我将监视器移动到该级别。请输入并退出该级别。新的和改进的代码如下所示

    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)
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
编辑2:

因此,我删除了较高的“Monitor.Enter/Exit”,并按照下面的建议将其替换为SyncLock,添加了使对象“private shared”的选项,使代码看起来像

    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)
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
我仍然得到相同的appCrash。

这样试试

Private Shared protectIt As New Threading.AutoResetEvent(True)
Private Sub TestSimul()
    protectIt.WaitOne() 'block forever
    '
    'code being protected
    ' when done
    protectIt.Set()
End Sub
这样试试看

Private Shared protectIt As New Threading.AutoResetEvent(True)
Private Sub TestSimul()
    protectIt.WaitOne() 'block forever
    '
    'code being protected
    ' when done
    protectIt.Set()
End Sub

您可以使用命名互斥体,该互斥体用于在同一操作系统中的进程之间进行同步

Public Class ACEEdits50

    Public Function runEdits(ByVal strNAACCRRecord As String) As EditMessageTransport
        Using m = New Threading.Mutex(False, "ACEEdits50")
            While Not m.WaitOne(20000) ' wait 20 seconds for mutex
                Console.WriteLine("Waiting for mutex")
            End While
            editsErrorHandler(Edit_RunEdits(_intsmfID, _strEditSetTag, _strEditLayoutTag, strNAACCRRecord, EE_SKIPFAIL, intErrCount, _ptrThis, _ptrEditsMessagerHandler), "Edit_RunEdits")
            objMessageTransport.intMstErrorCount = intErrCount
            objMessageTransport.objMstMessages = _objErrorMessages
            m.ReleaseMutex()
        End Using

    End Function

End Class

有关C#

中的更多参考信息,请参阅。您可以使用命名互斥体,用于在同一操作系统中的进程之间进行同步

Public Class ACEEdits50

    Public Function runEdits(ByVal strNAACCRRecord As String) As EditMessageTransport
        Using m = New Threading.Mutex(False, "ACEEdits50")
            While Not m.WaitOne(20000) ' wait 20 seconds for mutex
                Console.WriteLine("Waiting for mutex")
            End While
            editsErrorHandler(Edit_RunEdits(_intsmfID, _strEditSetTag, _strEditLayoutTag, strNAACCRRecord, EE_SKIPFAIL, intErrCount, _ptrThis, _ptrEditsMessagerHandler), "Edit_RunEdits")
            objMessageTransport.intMstErrorCount = intErrCount
            objMessageTransport.objMstMessages = _objErrorMessages
            m.ReleaseMutex()
        End Using

    End Function

End Class

有关C#

中的更多参考信息,请参阅。如何使用互斥锁?vb.net具有
SyncLock
功能,您确定这不起作用吗?除了将代码放入try/finally块(以便在所有情况下都调用Monitor.Exit)之外,这是标准模式。正如@DanielA.White所指出的,C#中提供的
SyncLock
关键字(或
lock
)语言可以为您实现这一点。您还应该使用相同的引用锁定objSync是否需要标记为静态?很难说这是否在实例类中,但如果是,每个实例可能都有一个objSync。使用互斥锁怎么样?vb.net有
同步锁
你确定这不起作用吗?除了将代码放入try/finally块(以便在所有情况下都调用Monitor.Exit)之外,这是标准模式。正如@DanielA.White所指出的,C#中提供的
SyncLock
关键字(或
lock
)语言可以为您实现这一点。您还应该使用相同的引用锁定objSync是否需要标记为静态?很难判断这是否在实例类中,但如果是,每个实例可能都有一个objSync。我尝试了@dbasnett定义的Threading.AutoResetEvent(True),没有运气。同样的结果。我尝试了@dbasnett定义的Threading.AutoResetEvent(True),没有运气。同样的结果。我确实使用了互斥锁,不完全是你的代码,但它似乎可以工作。其他一些解决方案也可能奏效。我这样说的原因是,有人告诉我,对DLL的一些调用是线程安全的,而其他调用则不是。我只是想保护那些我被告知有问题的人。最后,我将所有对DLL的调用包装在一个互斥体中,它起了作用。我确实使用了互斥体,不完全是您的代码,但它似乎起了作用。其他一些解决方案也可能奏效。我这样说的原因是,有人告诉我,对DLL的一些调用是线程安全的,而其他调用则不是。我只是想保护那些我被告知有问题的人。最后,我将所有对DLL的调用包装在一个互斥对象中,它成功了。