3

String、decimal?、DateTime? のいずれかの約 15 個のプロパティを持つオブジェクトがあります。またはint?複数のスレッドから操作されるこのクラスのコレクションがあります。最小限のコードを記述しながら、オブジェクトのプロパティの値がスレッド セーフな方法でアクセス (読み取り/書き込み) されるようにしたいと考えています。プライベートバッカーを使用して、すべてのプロパティのゲッターとセッターで明示的なロックを行う代わりに、そのような方法はありますか? 各プロパティに対して今やらなければならないことは次のとおりです。

public class ManyProperties
{
    private Object mLock = new Object;
    private string _personName;
    public string PersonName {
        get {            
             lock (mLock){
                 return _personName;
             }           
        }
        set { 
             lock (mLock){
                  _personName = value; 
             }
        }
    }

    private string _beginAmount;
    public decimal? BeginAmount {
        get {            
             lock (mLock){
                 return _beginAmount;
             }           
        }
        set { 
             lock (mLock){
                  _beginAmount = value; 
             }
        }
    }
}
4

1 に答える 1

4

通常、プロパティは単独では機能しません。正確で有効な値のペアなどを取得できない場合、各プロパティをスレッドセーフにしても役に立ちません。より適切なアプローチは、全体を不変にし、呼び出し元がスナップショットを取得できるようにすることです。

public class ManyProperties
{
    private readonly string _personName;
    public string PersonName { get { return _personName; } }

    private readonly decimal? _beginAmount;
    public decimal? BeginAmount { get { return _beginAmount; } }

    public ManyProperties(string personName, string decimal? beginAmount) {
       _personName = personName;
       _beginAmount = beginAmount;
    }
}

それから:

var snapshot = whatever.Properties;
var name = snapshot.PersonName;
...
var amount = snapshot.BeginAmount;

これらは常に一貫しています。さらに、ゼロロックがあります。参照の読み取り/更新も常にアトミックであるため、破損した値はありません。

重要なことは、次のことをしないことです。

var name = whatever.Properties.PersonName;
...
var amount = whatever.Properties.BeginAmount;

nameここでは、とamountが同じインスタンスに由来するという保証がなくなったためですManyProperties。誰かが 2 つのフェッチ間で参照を交換した可能性があります。

于 2013-02-19T18:56:20.067 に答える