6

私の WCF クライアント クラスではFaulted()、リモート サービスが例外をスローしてチャネルに障害が発生した場合でも、少なくとも正常にシャットダウンできるように、イベントを処理しています。これが私のコードです:

protected void RemoteDataRetriever_Faulted(object sender, EventArgs e)
{
    (sender as ICommunicationObject).Abort();
    this.Dispose();
    throw new ChannelTerminatedException("The remote service threw an unhandled exception and as a result the channel has been closed.");
}

したがって、私が期待するのは、クライアントがChannelTerminatedException手動でスローした を処理し、ユーザーなどにメッセージを送信できることです。代わりに、私の例外はSystem.ServiceModel.Diagnostics.CallbackException. いいよ。ただし、キャッチは次のとおりです。この CallbackException は ServiceModel ライブラリには存在せず、ジェネリックとして処理する以外に方法がないように見えますがException、単体テストには適していません。ここで一体何が起こっているのですか?どういうわけかそれを無効にして、最初に欲しかった例外をスローできますか?

4

2 に答える 2

4

結局のところ、「%SystemRoot%\Microsoft.net\Framework\v3.0\Windows Communication Foundation\ SMDiagnostics.dll System.ServiceModel.Diagnostics.CallbackException」と呼ばれるあまり知られていないアセンブリ内に内部クラスが詰め込まれており、それ自体には内部クラスのみが含まれています。ええと、それは、その例外を決してキャッチできないことを意味するため、悪臭を放ちます。しかし、上記の例外 (System.ServiceModel.Diagnostics.ExceptionUtility.ThrowHelperCallback(Exception innerException)) をインスタンス化するクラス/メソッドを突き止めることができ、CommunicationObject 内の仮想メソッド OnFaulted() によって呼び出されていることがわかりました。したがって、理論的には、CommunicationObject から派生したクラス (申し訳ありませんClientBase<T>) は、そのメソッドをオーバーライドして、ThrowHelperCallback() を呼び出さないように指示できます。つまり、実行可能な唯一の候補は、から派生したクラスです。ChannelFactoryBase<T>. 理論的には、面倒な Cal​​lbackException を抑制する独自のカスタム チャネル ファクトリを実装することもできますが、現時点では作業が多すぎるため、対処する必要があると思います。

編集: @Jeremy - 回線を介して戻ってくる SOAP エンベロープを調べると、予想どおり、一般的なエラーが発生していることがわかりました。これは、CallbackException がシリアル化されていないため、サーバー上で生成されていないことを示しています。

<s:Body>
    <s:Fault>
        <s:Code>
            <s:Value>s:Receiver</s:Value>
            <s:Subcode>
                <s:Value xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:InternalServiceFault</s:Value>
            </s:Subcode>
        </s:Code>
        <s:Reason>
            <s:Text xml:lang="en-US">The server was unable to process the request due to an internal error.  For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the &lt;serviceDebug&gt; configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework 3.0 SDK documentation and inspect the server trace logs.</s:Text>
        </s:Reason>
    </s:Fault>
</s:Body>
于 2010-02-16T16:27:03.460 に答える
2

System.ServiceModel.Diagnostics.CallbackExceptionサーバーで例外が発生しているため、 が表示されています。例外はクライアント アプリケーションのドメイン外で発生しているため、クライアントがアクセスできないタイプである可能性があります。コールバック メカニズムは、表示されている CallbackException を生成することでこれを処理します。System.TypeInitializationExceptionこれは、静的メンバーにアクセスするときに未処理の例外が発生したときにスローされるに似ています。これを適切に処理しようとしている場合は、サーバー側で例外を処理し、ソケットを閉じることをお勧めします。これにより、クライアントで処理可能な例外がトリガーされます。

于 2010-02-16T17:22:35.077 に答える