2016-04-04 10 views
3

NetTCPバインディングを使用するWCFサービスを作成しました。WCFサービスクライアントのクラッシュをキャッチできません

私のサービスはクライアントからアクセスされ、そのコールバックチャネルを保存し、それを後でクライアントに呼び出すために使用します(これは永続的なtcp接続です)。すべてうまくいきますが、突然クライアントを殺すことに決めたら、私は( "既存の接続はリモートホストによって強制的に閉じられました")SocketExceptionを取得します。

何を試しましたか?

  1. は、私は、コールバックチャネルを使用して、すべての方法でのtry-catch節を追加し、さらに上のレベルできました - WCFHost私のサービスを開始します。

  2. は、私は、チャネルと、コールバックチャネルの両方を取得し、チャネル障害が発生したイベントの処理方法追加しようとしました:要するに

    var channel = OperationContext.Current.Channel; 
    channel.Faulted += ChannelFaulted; 
    var callbackChannel = OperationContext.Current.GetCallbackChannel<CallbackInterface>(); 
    var comObj = callbackChannel as ICommunicationObject; 
    comObj.Faulted += ChannelFaulted; 
    

を、私はによってスローされた例外を処理しようとしていますクライアント - サーバー側。例外処理をサポートするWCFサービスのための2つの方法があります

+0

ありがとうございますが、私の問題は私が例外をキャッチすることができないため、チャンネルを中止または閉じることができません。 Visual Studioで見ることができる例外がありますが、コード内のどの行にもリンクされておらず、try-catch節はどれもそれをキャッチしません。 –

+0

もっとコードを提供できますか? –

答えて

0

多くの調査の結果、サーバがclienによってスローされた例外を検出することが判明しました私は私の質問で以前に述べたFaultedイベントを使用しています(私はデバッグ時にもっと忍耐強くて、例外が "自分のコードに到達するまで"すべてのレベルを "上がる"まで待つべきでした)。

しかし、イベントが遅すぎる場合にのみイベントがキャッチされることに注意してください。チャネルは既にnullです(OperationContext.Currentもそうです)。 IServiceBehaviorとIEndpointBehavior(IChannelInitializerを設定)を使用しても、System.ServiceModel.dllによってスローされた元のSocketExceptionをキャッチできませんでした。私のChannelFaulted()メソッドが最後に呼び出されたときに、クライアントが失敗したを検出する方法がありませんでした。

0

:serviceDebug.includeExceptionDetailInFaultsはincludeExceptionDetailInFaultsを定義 2.属性を「true」にホストの.configファイルに属性を「true」1.Defining

は、サービスクラスで。

例:

設定ファイルのソリューション:

<behaviors> 
<serviceBehaviors> 
<behavior name=”ServiceBehavior”> 
<serviceMetadata httpGetEnabled=”true”/> 
<serviceDebug includeExceptionDetailInFaults=”true”/> 
</behavior> 
</serviceBehaviors> 
</behaviors> 

帰属クラスソリューション:

[ServiceBehavior(IncludeExceptionDetailInFaults=true)] 
public class CustomersService : ICustomersService 
{ 
private CustomerDetail customerDetail = null; 

...などExceを投げる

ption includeExceptionDetailInFaultsをtrueに設定するのは、WCFで例外をサポートする最初のステップです。

次の手順は、サービスがFaultException例外(System.ServiceModel.FaultException名前空間のクラス)をスローすることです。 WCFホストからWCFクライアントに例外をスローする場合は、通常のExceptionクラスを使用するだけでは不十分です。 WCFバインディングで例外をスローするには、FaultExceptionクラスを使用する必要があります。

FaultException例
をキャッチ
try 
{ 
//Try to do stuff 
} 
catch 
{ 
throw new FaultException(“Full ruckus!”); 
} 

:FaultException例を投げる

を今WCFクライアントはFaultExceptionをキャッチすることができます...

try 
{ 
//Client calls services off the proxy 
} 
catch(FaultException fa) 
{ 
MessageBox.Show(fa.Message); 
} 

はフォルト例外のタイプを区別 FaultExceptionクラスは、WCF例外の汎用クラスです。どのようなタイプのFaultExceptionsが発生するかを調べるには、FaultCodeクラスを使用します。 WCFサービスでのFaultCodeの実装は次のようなものになります:WCFクライアントで

try 
{ 
    //Connect to a database 
} 
catch 
{ 
    throw new FaultException(“Full ruckus!”, new FaultCode(“DBConnection”)); 
} 

を、のFaultCodeの実装は次のようなものになります。詳細については、

try 
    { 
     //Call services via the proxy 
    } 
    catch(FaultException fa) 
    { 
     switch(fa.Code.Name) 
     { 
     case “DBConnection”: 
      MessageBox.Show(“Cannot connect to database!”); 
      break; 
     default: 
      MessageBox.Show(“fa.message”); 
      break; 
     } 
    } 

をあなたはhereを見ることができますし、またhere

+0

答えをありがとう。私はServiceBehaviorを使用しようとしましたが、私はまだ例外をキャッチできませんでした(私はデバッガでApplyDispatcherBehaviorのコードを見ることができましたが) –

+0

@G。 madn私が付けた2番目のリンクを試しましたか? –

+1

はい。あなたが与えた情報は、いったん捕らえられると、エラーを処理するのに非常に便利です。しかし、私の問題は、私が最初にエラーをキャッチすることができなかったということでした。 私が実際に探していたのは、クライアントのクラッシュを検出して、サービスが存在しないクライアントのアイドル状態の接続を保存しないようにする方法でした。 –

関連する問題