1

WPF アプリケーションにいくつかの WCF サービスがあり、次の方法でそれらを開きます。

private void StartSpecificWCFService(IService service, string url, Type serviceInterfaceType)
{
    ServiceHost serviceHost = new ServiceHost(service, address);
    serviceHost.AddServiceEndpoint(serviceInterfaceType, new NetNamedPipeBinding(), url);
    serviceHost.Open();
    //sign to serviceHost.Faulted ??
    _wcfServicesHolder.Add(serviceHost); //A dictionary containing all my services
}

サービス属性は次のとおりです。

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]

サービスはログ サービスとイベント サービスであり、他のプロセスから多くの呼び出しを受けます。名前付きパイプが最速であり、プロセスが同じコンピューターで実行されるため、名前付きパイプを使用します。

私の質問は、これらのサービスを常に稼働させるにはどうすればよいですか?

  1. _wcfServicesHolder を反復し、サービスが開いているかどうかを確認するポーリング タイマー
  2. serviceHost.Faulted イベントに署名します。

また、サービスが障害状態になった後、(別のプロセスで) クライアントを再作成する必要がありますか? または、同じチャネルでメッセージをブロードキャストできますか?

私が受け取る例外は次のとおりです。

There was no endpoint listening at net.pipe://localhost/LoggingService that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details
4

2 に答える 2

1

InstanceContextMode = InstanceContextMode.Singleサービスに同時スレッド アクセスがあるのはなぜですか? サービスはある種のメモリー内スレッドセーフ状態を保持していますか? そうでない場合は、使用するサービスをリファクタリングしてみる価値があるかもしれませんInstanceContextMode.PerCall。これは、WCF サービスを構成する際のデフォルトであり、推奨される選択肢です。WCF は主にサービス指向アーキテクチャを実装するためのテクノロジであり、 SO 設計原則PerCallのステートレス原則に違反する以外のモードを使用します。

これをサポートするために、 でサーバー側の障害が発生したInstanceContextMode.Single場合、これはサービスで重大な問題が発生したことを示しています。サービス内で維持していた状態はすべて失われます。クライアントは、再接続して通常どおりに再開するだけでは期待できません。

最終的に何InstanceContextModeを使用するにしても、クライアントが一定時間接続していない状態でチャネルが開いたままになると、チャネルに障害が発生します。TCP (または信頼できるセッションを明示的に公開する任意のプロトコル) を介して、信頼できるセッションで非アクティブ タイムアウトを指定できますが、パイプを使用するそのようなオプションはありません。

パイプを使用して、構成されたタイムアウトより長くチャネルを開いたままにすると、チャネルが使用できなくなります。アプリケーションの存続期間中、チャネルをサービスに対して開いたままにしておくことに関心がある場合は、チャネル障害イベントにサブスクライブし、プロキシを再作成できます。あなたが示唆するように、別のオプションは、チャネルに沿ってポーリングを続けて、それを維持することです。

于 2013-05-24T16:22:04.077 に答える
1

サービス ホストを稼働状態に保つには、2 番目のオプション (サービス ホストで障害が発生したイベントをサブスクライブする) を使用します。障害が発生した場合は、サービス ホストを中止し、新しいインスタンスを新たに作成し、障害が発生したイベント ハンドラーを再配線して、サービス ホストを開く必要があります。

このシナリオに関する公式ドキュメントはあまりありませんが、探しているものについて説明している msdn ブログの古い投稿を次に示します。

http://blogs.msdn.com/b/drnick/archive/2007/01/16/restarting-a-failed-service.aspx

クライアントに関しては、チャネルに障害が発生したときに、サーバーへのチャネルを再作成する必要もあります。

于 2013-05-24T16:43:06.253 に答える