4

データベースから読み取り、結果を返す WCF サービスを作成しました。パフォーマンス上の理由から、サービスの起動時にテーブルをキャッシュしたいと思います (これは Windows サービスの OnStart で発生します)。しかし、WCF にはコンストラクターのようなものはありません (そうですか?) ので、私が思いついた最善の方法は、Init() 関数を作成し、次のように呼び出すことです。

protected override void OnStart(string[] args)
{
    mServiceHost = new ServiceHost(typeof(DLSService.DLSService), new Uri("http://localhost:8000/DLS"));
    mServiceHost.AddServiceEndpoint(typeof(DLSService.IDLSService), new BasicHttpBinding(), "ServicesHost");
    ((DLSService.DLSService)mServiceHost.SingletonInstance).Init();
    mServiceHost.Open();
}

しかし、SingletonInstance を使用して正しい型にキャストすることは、私にはそれほど優雅に思えません。WCF でコンストラクターのような機能を実現するためのよりエレガントな方法はありますか?

4

4 に答える 4

3

これは、 MbCacheなどのメモ化ライブラリで解決できます。私たちはまさにあなたが探していることをしています。アプリケーションの起動時に、キャッシュする各サービス操作を呼び出します。MbCache は、キャッシュの有効期限が切れるまで、連続した呼び出しの結果をキャッシュします (つまり、結果を取得するためのデータベース ラウンドトリップはありません)。

MbCache にはかなりの複雑さが伴いますが、実行すると非常にうまく機能し、すべてのキャッシュ ロジックを処理してくれます。

于 2013-07-10T07:18:15.467 に答える
3

推奨されるベスト プラクティスは、WCF で呼び出しごとのアクティブ化モデルを使用し、サービスを完全にステートレスに保つことです。

つまり、クライアントがリクエストを行うたびに、サーバー側でサービス実装クラスのインスタンスが作成され、リクエストされたサービス呼び出しが行われ、サービス クラスが再び破棄されます。

したがって、初期化コードをサービス実装クラスのコンストラクターに入れるのは、非常に悪い考えです。それは、すべてのリクエストに対して実行されることになります。

あなたができることは、キャッシュしたいテーブルを永続的なキャッシュ、例えばAppFabricキャッシュのようなものにロードするある種のロジック(サービスクラス、または何らかのサポートコード、例えば管理インターフェースのいずれか)を持つことです。 . 完了すると、リクエストを処理する複数のサービス インスタンスがその共通キャッシュを使用して、パフォーマンスを向上させることができます。

于 2013-07-10T06:55:24.733 に答える
1

インターフェイスを使用IInstanceProviderしてサービスを作成できます。詳細については、この記事を参照してください。コードの例を次に示します。

public class CustomInstanceProvider:IInstanceProvider
{

    public object GetInstance(InstanceContext instanceContext)
    {
        return GetInstance(instanceContext, null);
    }

    public object GetInstance(InstanceContext instanceContext, System.ServiceModel.Channels.Message message)
    {
        return new DLSService.DLSService();
    }

    public void ReleaseInstance(InstanceContext instanceContext, object instance)
    {            
    }
}

var mServiceHost = new ServiceHost(typeof(DLSService.DLSService), new Uri("http://localhost:8000/DLS"));   
mServiceHost.AddServiceEndpoint(typeof(DLSService.IDLSService), new BasicHttpBinding(), "ServicesHost");

foreach (var channelDispatcher in mServiceHost.ChannelDispatchers.OfType<ChannelDispatcher>())
{
    foreach (var endpointDispatcher in channelDispatcher.Endpoints)
    {
        endpointDispatcher.DispatchRuntime.InstanceProvider = new CustomInstanceProvider();
    }
}
mServiceHost.Open();
于 2013-07-10T06:58:54.597 に答える