netNamedPipeBindingを使用してWCFシングルトンサービスを作成しました。チャネル例外が発生すると、チャネルは障害状態のままになり、後続のすべての操作で例外がスローされます。どうすればこれを防ぐことができますか?TimeoutException、またはその他の一般的な例外のいずれかを使用して、1つの操作のみを失敗させ、サービスを応答不能にしないようにします。
2 に答える
サーバー側の例外をFaultExceptionにラップする必要があります。ワイヤの両端を制御し、両端が.NETの場合は、.NET例外をにラップFaultException<T>
してクライアントに送り返すだけです。そうすれば、チャネルは引き続き使用可能です。
詳細については、MSDNの契約とサービスでの障害の指定と処理を参照してください。さらに、CodeProjectに関するこの記事と 、同じトピックでWCFFaultExceptionを使用する理由に関するこのブログ投稿を確認してください。
また、作業を楽にするために、サーバー側に実装できるIErrorHandlerインターフェイスを確認して、例外をグローバルにキャッチし、それらを障害に変換してください。また、このトピックに関する多くのブログ投稿、つまりIErrorHandler:一般的なFault Converterまたはその他の多くのブログ投稿(詳細についてはBingまたはGoogle)も参照してください。
作業をさらに簡単にするために、IErrorHandlerを動作として実装できます。これは、サービス構成で、またはサービスクラスに属性を設定することにより、サービスをオンまたはオフにすることができます。インターネットにはかなりの数の実装があります。私が気に入っているのはここにあります:便利なWCFの動作:IErrorHandler。
別の方法があります。複数のリクエストに単一のインスタンスを使用する代わりに、リクエストごとにクライアントプロキシをインスタンス化できます。このようにして、チャネルが障害状態になった場合でも、とにかく破棄されます。
IDisposableであることに加えて、チャネルを破棄するべきではないため、これは少し注意が必要です。
それは機能しません:
using(var channel = channelFactory.CreateChannel())
{
return channel.ServiceMethod(parameter);
}
代わりに、次のことを行う必要があります。
public static class Service<T>
{
public static ChannelFactory<T> _channelFactory = new ChannelFactory<T>("");
public static TResult Use<TResult>(Func<T, TResult> func)
{
TResult output;
var channel = (IClientChannel)_channelFactory.CreateChannel();
bool success = false;
try
{
output = func((T)proxy);
channel.Close();
success = true;
}
finally
{
if (!success)
{
proxy.Abort();
}
}
return output;
}
}
return Service<IService>.Use(channel =>
{
return channel.ServiceMethod(parameter);
});