1

下面的函数采用任何 wcf 服务方法并调用它。

Private Function ServiceCall(ByVal functionToCall As ServiceDelegate(Of IEmpService)) As Object
    Dim channel As New ChannelFactory(Of IEmpService)(_endPoint)
    Dim serv As IEmpService
    Dim result As Object = Nothing
    Dim mostRecentExp As Exception = Nothing
    Dim noOfRetries As Integer = My.Settings.NoOfRetries
    Dim initialDelay As Integer = My.Settings.InitialDelayInMS

    serv = channel.CreateChannel()

    For i As Integer = 0 To noOfRetries

        Try
            result = functionToCall.Invoke(serv)
            mostRecentExp = Nothing
            Exit For
        Catch cte As ChannelTerminatedException
            mostRecentExp = cte

            Thread.Sleep(initialDelay * (i))
        Catch enf As EndpointNotFoundException
            mostRecentExp = enf
            Thread.Sleep(initialDelay * (i))
        Catch stb As ServerTooBusyException
            mostRecentExp = stb
            Thread.Sleep(initialDelay * (i))

        Catch vf As FaultException(Of ValidationFault)
            'no retry

        Catch exp As Exception 'any other exception 
            mostRecentExp = exp
            Thread.Sleep(initialDelay * (i))

        Finally
            If channel.State = CommunicationState.Faulted Then
                channel.Abort()
            Else
                channel.Close()
            End If
        End Try
    Next
    If mostRecentExp IsNot Nothing Then
        Throw New ServiceExceptions(String.Format("Call to method {0} failed", functionToCall.ToString()), mostRecentExp.InnerException)
    End If
    Return result
End Function

我根据我得到的异常类型确定是否需要重试,这一切都很好。我面临的问题是result = functionToCall.Invoke(serv)结果是一个对象并且它可以包含一个自定义错误对象,在这种情况下它不会是一个例外。要解决错误,我可以做类似的事情: If TypeOf result Is SaveAddressResponse Then ElseIf TypeOf result Is SaveDetailResponse Then End If 看起来很乱所以想知道我是否可以使用委托从return对象中获取错误?

4

1 回答 1

0

听起来您应该考虑让所有这些响应实现一个通用接口,例如IFailureReporter,它允许您以统一的方式处理任何错误。然后你需要转换到那个接口(如果你的所有响应都实现了那个接口,你可以无条件地这样做),并以这种方式检查错误。

编辑:如果这不可行,还有另一种可能的方法,将每个类型的委托存储在字典中。目前还不清楚你想对错误什么,或者它在你的每个响应对象中是如何表示的......但是如果你知道响应对象的确切类型(不仅仅是类型他们'重新兼容)。这是 C# 代码,但类似的 VB 代码应该是可行的 - 我不太可能做对:

private static readonly Dictionary<Type, Func<object, string>>
     ErrorExtracters = new Dictionary<Type, Func<object, string>>
{
    { typeof(SaveAddressResponse), response => ((SaveAddressResponse) response).Error,
    { typeof(OtherResponse), response => ((OtherResponse) response).ErrorMessage,
    ...
};

然后:

Func<object, string> extractor;
if (ErrorExtractors.TryGetValue(result.GetType(), out extractor))
{
    string error = extractor(result);
    if (error != null)
    {
        ...
    }
}
于 2012-09-19T05:55:18.327 回答