Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.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 VBA-在引发异常之前检查System.ServiceModel.Channels.ServiceChannel故障状态_.net_Exception_Vba_Serialization - Fatal编程技术网

.net VBA-在引发异常之前检查System.ServiceModel.Channels.ServiceChannel故障状态

.net VBA-在引发异常之前检查System.ServiceModel.Channels.ServiceChannel故障状态,.net,exception,vba,serialization,.net,Exception,Vba,Serialization,我被迫连接到我正在开发的VBA工具中的某个.net服务。我使用一个函数返回缓存的实例,如果还没有创建,则创建一个新实例 如果对象出现任何错误(例如连接超时),下次尝试使用它时,我会得到错误 通信对象System.ServiceModel.Channels.ServiceChannel无法用于通信,因为它处于故障状态 我在网络上看到过这个错误,但都是在有try-catch块的适当语言中出现的 与其等到缓存实例被使用时发生此错误并在“On error Goto”语句中处理它,不如在检索缓存对象以供使

我被迫连接到我正在开发的VBA工具中的某个.net服务。我使用一个函数返回缓存的实例,如果还没有创建,则创建一个新实例

如果对象出现任何错误(例如连接超时),下次尝试使用它时,我会得到错误

通信对象System.ServiceModel.Channels.ServiceChannel无法用于通信,因为它处于故障状态

我在网络上看到过这个错误,但都是在有try-catch块的适当语言中出现的

与其等到缓存实例被使用时发生此错误并在“On error Goto”语句中处理它,不如在检索缓存对象以供使用时防止它发生。我在任何地方都找不到这个东西的对象模型,在初始化的对象上设置一个手表就会显示出来。在检索时,我可以使用什么属性或测试来确定对象是否处于故障状态

Private Function GetMRLDIntegrationService() As Object
    Const ServiceAddress = "service:mexAddress=""net.tcp://hydfwdvweb001/Integration/MrldIntegrationService.svc/Mex""," & _
            "address=""net.tcp://hydfwdvweb001/Integration/MrldIntegrationService.svc/""," & _
            "contract=""IMrldSimplexIntegration"", contractNamespace=""http://tempuri.org/""," & _
            "binding=""SimplexIntegration"", bindingNamespace=""http://tempuri.org/"""
    Static cachedInstance As Object
    If Not cachedInstance Is Nothing Then
        ''//If *DETECT ERROR STATE HERE* Then Set cachedInstance = Nothing
    End If
    If cachedInstance Is Nothing Then Set cachedInstance = GetObject(ServiceAddress)
    If cachedInstance Is Nothing Then Err.Raise 1, , _
        "The MRLD server did not respond to the request to provide the service object."
    Set GetMRLDIntegrationService = cachedInstance
End Function
在其他地方,在另一种方法中,这就是错误发生的地方,而此时要优雅地处理错误已经太晚了:

Private Sub FillFromRiskID(ByVal riskID As String)
    ...
    Process_MRLD_Result GetMRLDIntegrationService().GetSerializedRisk(riskID, "1", uName, pWord)
    ...
End Sub

感谢您的帮助

这是一个有效的解决方案,但我正试图避免,因为它很难看,而且在大多数情况下,缓存对象没有问题,这是浪费时间。GetSerializedRisk在某些情况下需要15秒才能返回,即使返回值是无效的登录名或错误的请求id

Private Function GetMRLDIntegrationService() As Object
    Const ServiceAddress = "service:mexAddress=""net.tcp://hydfwdvweb001/Integration/MrldIntegrationService.svc/Mex""," & _
            "address=""net.tcp://hydfwdvweb001/Integration/MrldIntegrationService.svc/""," & _
            "contract=""IMrldSimplexIntegration"", contractNamespace=""http://tempuri.org/""," & _
            "binding=""SimplexIntegration"", bindingNamespace=""http://tempuri.org/"""
    Static cachedInstance As Object
    If Not cachedInstance Is Nothing Then
        ''If *DETECT ERROR STATE HERE* Then Set cachedInstance = Nothing
        On Error GoTo errorStateDetected
        cachedInstance.GetSerializedRisk "1", "1", "dummyrequest", "dummyrequest"
        GoTo everythingIsFine
errorStateDetected:
        Set cachedInstance = Nothing
        Resume everythingIsFine
everythingIsFine:
        ''//I just wasted a bunch of time
    End If
    If cachedInstance Is Nothing Then Set cachedInstance = GetObject(ServiceAddress)
    If cachedInstance Is Nothing Then Err.Raise 1, , _
        "The MRLD server did not respond to the request to provide the service object."
    Set GetMRLDIntegrationService = cachedInstance
End Function

此替代解决方案为GetService函数提供了重置缓存对象的选项(即,如果发生错误),问题是我无法找到使用此功能的方法,以便可以轻松重置故障状态错误,但在处理实际错误之前,其他错误不会导致冗余错误请求

Private Function GetMRLDIntegrationService(Optional ByVal reset As Boolean = False) As Object
    Const ServiceAddress = "service:mexAddress=""net.tcp://hydfwdvweb001/Integration/MrldIntegrationService.svc/Mex""," & _
            "address=""net.tcp://hydfwdvweb001/Integration/MrldIntegrationService.svc/""," & _
            "contract=""IMrldSimplexIntegration"", contractNamespace=""http://tempuri.org/""," & _
            "binding=""SimplexIntegration"", bindingNamespace=""http://tempuri.org/"""
    Static cachedInstance As Object
    If reset Then Set cachedInstance = Nothing
    If cachedInstance Is Nothing Then Set cachedInstance = GetObject(ServiceAddress)
    If cachedInstance Is Nothing Then Err.Raise 1, , _
        "The MRLD server did not respond to the request to provide the service object."
    Set GetMRLDIntegrationService = cachedInstance
End Function
以及调用函数:

''/*If the cached object is in an error state there's no way to detect it without making a request, but
'making even a dummy request each use just to check would waste dozens of precious seconds per request,
'so this routine carefully makes the intended request, catches the error that might occur, then resets
'the connection and tries the request again. The upside is that a service object in an error state
'will be resolved immediately and transparently by opening a new connection as needed. The downside
'is that if any other error occurs (such as a 1 minute timeout error), the first occurrence will
'be a non-breaking error and it will actually repeat the error a second time before notifying the user,
'doubling the amount of time it takes any error to propogate. (In the case of a 1 minute time-out
'occurring, the request would occur twice for a total of 2 minutes delay until the application becomes
'responsive again.)*/
Private Sub FillFromRiskID(ByVal riskID As String)
    Const uName As String = "perftest1"
    Const pWord As String = "****"
    Dim result As String

    On Error GoTo retryGet
    Process_MRLD_Result GetMRLDIntegrationService().GetSerializedRisk(riskID, "1", uName, pWord)
    GoTo finally
retryGet:
    Resume retryGet2: 'Resets the error state so that a new error can be thrown
retryGet2:
    On Error GoTo invalidConnection
    Process_MRLD_Result GetMRLDIntegrationService(reset:=True).GetSerializedRisk(riskID, "1", uName, pWord)
finally:
    Exit Sub
invalidConnection:
    MsgBox "Error connecting to MRLD: " & Err.Description, vbCritical, "Fill From MRLD"
End Sub

无法执行此操作,因为虚拟请求的处理时间与正常请求的处理时间一样长,每个调用的时间都要加倍。