1

グローバル アプリケーション構成として使用するクラスを作成しようとしています。このクラスは次のようになります。

public class GlobalConfiguration
    {    
    private static volatile GlobalConfiguration _current;
    private static ReaderWriterLockSlim _instanceLock = new ReaderWriterLockSlim();
    public ICipher Cipher {get;set;}
    public IHasher Hasher {get;set;}
    //....

    public static GlobalConfiguration Current
    {
        get
        {
            if (_current == null)
            {
                _instanceLock.EnterWriteLock();
                if (_current == null) _current = new GlobalConfiguration();
                _instanceLock.ExitWriteLock();
            }
            return _current;
        }
    }
}

今、私は次のことができるようになりたいです:

GlobalConfiguration.Current.Cipher = new AesCipher();

私が今心配しているのは、私の GlobalConfiguration クラスはシングルトンとして設計されていますが、Cipher プロパティはどうなるのでしょうか? _instanceLock は GlobalConfiguration クラスに使用されますが、それを使用して Cipher プロパティをスレッドセーフにする方法もわかりません。

4

2 に答える 2

2

Brian Gideon の回答に加えて、プロパティへのアクセスをロックしてCipherも、このプロパティが設定されているインスタンスのメンバーへのアクセスは制限されないことに注意してください。

Cipherのような方法でマルチスレッド環境でプロパティの値を操作する必要がある場合は、( 内から) へのGlobalConfiguration.Current.Cipher.DoSomething()アクセスもロックしてください。または、可能であれば、不変にすることをお勧めします。DoSomething()AesCipherAesCipher

具体的には当てはまらないかもしれませんがAesCipher、これは「一般的なソリューション」の説明です。

于 2013-09-13T20:25:47.147 に答える
1

_instanceLockなどのインスタンス メンバーに対してロックを実行するために静的ロックを使用しないでくださいCipher_instanceLockロックは、シングルトンの作成を保護することを目的としています。別のロックを使用して、プロパティでロックを実行しCipherます。複数の目的で 1 つのロックを使用することは避けてください。さまざまな目的...さまざまなロック。

実際、これは一般的にかなり標準的なアドバイスです。静的ロック メカニズムを使用すると、同じアプリケーション ドメイン内の同じクラスのすべてのインスタンスがロックを求めて競合する必要があります。静的メンバーが参照されていないときにインスタンス プロパティでこのようなことを行うと、多くの不要なロック競合が発生する可能性があります。

また、本当にここで使用する必要がありReaderWriterLockSlimますか?ほとんどの場合、実際には単純な古い よりも遅くなりますlock。さらに進んで、二重チェックのロックパターンを本当に使用する必要がありますか。適切な場合もあれば、やり過ぎの場合もあります。詳細については、C#での Jon Skeet のシングルトン実装パターンをご覧ください。

于 2013-09-13T19:59:44.623 に答える