4

C# で Windows サービスを作成しました。それは機能し、うまく機能しています。Windows サービスに WCF サービスを追加して、クライアント アプリケーションが Windows サービスに接続し、Windows サービスからステートフルな情報を取得できるようにしました。

次のように、同じサービス インスタンスを使用してすべてのクライアントからのすべての要求を処理するように、WCF サービスをシングルトンに構成しました

すべてのクライアントが接続でき、WCF サービス内の同じステートフル情報にアクセスできます。ただし、次のような独特の動作に遭遇しています。

改訂: Windows サービス内で
WCFサービス コントラクトをインスタンス化します。インスタンス化時に割り当てられたステートフルな情報は、サービスに接続するすべてのクライアントで利用できます。

ただし、 (クライアントによってではなく) Windows サービスから直接サービス コントラクトインスタンスに追加されたステートフルな情報は、サービスに接続するクライアントには表示されません。これは、サービス コントラクトの 2 つのインスタンスがあるかのようです。1 つは Windows サービス用で、もう 1 つは WCF サービスに接続するクライアント用です。

WCF サービスをインスタンス化し、Windows サービス内で利用可能なステートフル情報にアクセスできるようにするための推奨される (最良の) 方法は何ですか?

4

3 に答える 3

2

WCF が呼び出しごとに新しいインスタンスを作成するか、インスタンスを再利用するかどうかが問題にならないように、状態を静的メンバーに保持することで、これを回避することをお勧めします。これにより、問題が解決され、コードが簡素化されます。

于 2009-08-14T13:57:58.733 に答える
2

WCF サービスにステートフルな情報が必要なのはなぜですか? それをデータベースに保存して、必要なときにアクセスできませんか?

WCF では、サービスのシングルトン インスタンスを使用できますが、絶対に必要な場合を除き、通常はこれを使用しないことをお勧めします。通常、ステートフルな情報をデータベース テーブルなどに格納し、クライアントが通常の呼び出しごとの WCF サービスを使用してアクセスできるようにすると、より簡単で、より適切に拡張できます。

更新:
OK、別のアイデア: とにかく ServiceHost は常に 1 つしかありません。「呼び出しごと」のインスタンス化モードを選択した場合 (すべての主要な専門家が推奨するように)、ServiceHost は、着信要求を処理するワーカー スレッドのスレッド プールを割り当てます。

WCF サービスがシングルトンである必要があるのはなぜですか? 「呼び出しごと」を使用しても、NT サービスのステートフルな情報を取得できませんか?

リクエストが届き、サービス オブジェクト (サービス インターフェイスを実装するサービス クラス) のインスタンスが作成されます。現在、NT サービスのステートフル情報にどのようにアクセスしていますか? 実際に必要なときに、新しく作成されたサービス インスタンスからもそれを行うことができませんでしたか?

NT サービスにステートフルな情報が保持されている場合は、同時アクセスが適切に処理されるようにする必要があります。これは、WCF サービス クラスがシングルトンであるかどうかとはまったく関係ありません。

更新 2:
「OperationContext.Current.Host」を使用すると、実行中のサービス メソッド内で特定のサービス インスタンスをホストする ServiceHost にアクセスできます。実際の NT サービス インスタンスにアクセスできるかどうかはわかりません。ただし、追加のプロパティ「ListOfClients」を持つ独自のカスタム ServiceHost 子孫を作成すると、実行中の任意のサービス インスタンスからいつでもそのリストにアクセスできるはずです。

注意:任意の時点で処理されるサービス リクエストの数に制限はないため、リストの読み取りはスレッド セーフである必要があり、Windows NT サービスからのリストの更新はさらに「危険」であり、これらの同時実行の問題を解決する必要があります。考慮に!リストを更新する必要がある場合は、リストをロックしてください。そうしないと、予期しない結果が生じる可能性があります。

マルク

于 2009-08-14T13:59:52.180 に答える
1

InstanceContextMode.Single を設定すると、ServiceHost はサービスの単一インスタンスを構築し、それをすべての呼び出しに使用します。しかし、自分でインスタンスを構築し、共有状態への参照を設定したいようです。その場合、それは「既知のインスタンス」パターンと呼ばれ、次のようにインスタンスを ServiceHost コンストラクターに渡すことで実現できます。

var svc = new MyServiceClass(state);
var host = new ServiceHost(svc, new Uri(..), ...);
...

ServiceHost は、渡されたインスタンスをすべての呼び出しに使用します。

シングル インスタンス モードを使用する際の重要な考慮事項 (オブジェクトが "well-known" であるか、ServiceHost によって構築されているか) は、スレッド化です。デフォルトでは、WCF はサービス インスタンスごとに 1 つのスレッドのみを同時に実行できます。したがって、PerCall インスタンス モードでは、複数のサービス インスタンスがあるため、複数の同時スレッドをサポートでき、通常の条件下でスループットが向上します。ただし、単一インスタンス モードでは、サービス インスタンスが 1 つしかないため、一度に実行できるスレッドは 1 つだけです。サービスによって異なりますが、同時実行モードを複数に切り替えることは理にかなっています。これにより、サービス インスタンスへの複数の同時スレッドが許可されますが、サービスの実装はスレッド セーフである必要があります。

ここにいくつかの良いドキュメントがあります: http://msdn.microsoft.com/en-us/library/ms731193.aspx

于 2009-10-17T16:11:11.457 に答える