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 に答える