下面的函数接受任何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
对象中获取错误?
答案 0 :(得分: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)
{
...
}
}