10

私たちの SharePoint/ASP.NET 環境には、すべて共通のインターフェイスから派生した一連のデータ取得クラスがあります。私は、WCF を使用して他の SharePoint ファームとリモートで通信できるデータ リトリーバーを作成するタスクを割り当てられました。私が現在実装している方法は、シングルトンChannelFactory<T>が静的コンストラクターで作成され、リモート データ リトリーバーの各インスタンスによって再利用されて、個々のプロキシ インスタンスが作成されるというものです。ChannelFactoryはアプリ ドメインで 1 回だけインスタンス化され、その作成はスレッド セーフであることが保証されているため、これはうまく機能すると考えました。私のコードは次のようになります。

public class RemoteDataRetriever : IDataRetriever
{
    protected static readonly ChannelFactory<IRemoteDataProvider>
        RequestChannelFactory;

    protected IRemoteDataProvider _channel;

    static RemoteDataRetriever()
    {
        WSHttpBinding binding = new WSHttpBinding(
            SecurityMode.TransportWithMessageCredential, true);

        binding.Security.Transport.ClientCredentialType =
            HttpClientCredentialType.None;

        binding.Security.Message.ClientCredentialType =
            MessageCredentialType.Windows;

        RequestChannelFactory = 
            new ChannelFactory<IRemoteDataProvider>(binding);
    }

    public RemoteDataRetriever(string endpointAddress)
    {
        _channel = RemoteDataRetriever.RequestChannelFactory.
            CreateChannel(new EndpointAddress(endpointAddress));
    }
}

私の質問は、これは良いデザインですか?ChannelFactoryが作成されたら、単に呼び出すために使用しているだけなので、スレッドセーフについて心配する必要はないと考えましたが、CreateChannel()間違っていますか? スレッド化の問題を引き起こす可能性のある舞台裏で状態を変更したり、ファンキーなことを行ったりしていませんか? さらに、手動で破棄するコードをどこかに配置する必要がありますか (静的ファイナライザー?)、ChannelFactoryまたは IIS が再起動されるたびにすべてのクリーンアップ作業が行われると想定できますか?

関連: ChannelFactory の再利用戦略

4

3 に答える 3

3

「このシングルトンの設計は良いですか」から、シングルトンの実装は問題ありません。これはスレッドセーフであり、ChannelFactory<T>もスレッドセーフです。

また、リソースのクリーンアップについて心配する必要もありません。IDisposable を実装するための Microsoft のガイドラインにChannelFactory<T>従っていると仮定すると、何らかのリークの問題は発生しません。アプリケーション ドメインが破棄されると、ガベージ コレクションが作成され、その時点ですべてがクリーンアップされます。ファイナライザーは、Dispose の呼び出しで通常行うクリーンアップを実行します。ChannelFactory<T>

ただし、「キャッシュすべきかChannelFactory<T>」という観点からは、どのバージョンの .NET を使用しているかを示していないため、言うのは困難です。ただし、あなたが指摘する記事は、.NET 3.0 SP1 以降を使用している場合、実際にこれを行う必要はなくClientBase<T>、クライアント コードで必要な場所にプロキシを作成できることを示しています (から派生すると仮定)。このようなファクトリーパターンではありません。

于 2010-02-15T08:46:15.403 に答える
0

「シングルトン」が新しく構築されたチャネルを返すだけである限り、スレッドの安全性について心配する必要はありません。必要に応じて、いつでも static 宣言に volatile キーワードをスローして、コンパイラの最適化が弱体化するのを防ぐことができますが、この場合は必要ないと思います。

長期的な柔軟性について自問自答してみてください。たとえば、後でこの CreateChannel メソッドに状態を追加することにした場合はどうなるでしょうか。おそらく、最大 10 個のチャネルを作成し、その後それらを再利用し始めるようなことを行うでしょう。これを行うためにシングルトンを簡単に変更できますか?

あなたの答えはおそらく「はい」ですが、複数のサーバーに垂直にスケーリングするとどうなるでしょうか? シングルトンでは不十分な場合があります。インスタンス/サーバー間で状態を共有する何らかの方法が必要です (データベース、分散キャッシュなど)。状態を共有する方法によっては、静的なコンテキストで行うのが難しい場合があります。

于 2010-02-15T05:12:56.403 に答える
0

この記事で Daniel Vaughan は、Singleton マネージャー オブジェクトにチャネルをキャッシュすることを提唱していますが、ChannelFactory をキャッシュすることは決してありません。これまでのところ、このアプローチを問題なく使用してきました...

そうする利点は次のとおりです。

「チャネルが障害状態になると、キャッシュから削除され、次に要求されたときに再作成されます...」

  • セキュリティ ネゴシエーションは 1 回だけ実行されます。
  • 使用するたびにチャネルを明示的に閉じる必要がなくなります。
  • 初期化機能を追加できます。
  • プロキシがサーバーと通信できない場合、早期に失敗する可能性があります。
于 2010-10-01T10:27:04.013 に答える