2016-06-15 11 views
0

私はコマンドパターンをC#で使用しています。 RequiredDataという名前のプロパティを含むクラスがあります。C#で複数のスレッドのすべての派生クラスに同じインスタンスを共有するにはどうすればよいですか?

public class RequiredData 
{ 
    public Class1 class1 { get; set; } 
    public int value1 {get; set;} 
} 

抽象クラスBaseCommandがあるとcommand1 , command2 etcのようないくつかの派生クラスがあります。私は、全体のプロセスの間にしたい

command1.Execute(); 
command2.Execute(); 

更新され、すべてのコマンドから使用できる共有RequiredDataオブジェクトを持っている:

abstract class BaseCommand : ICommand { } 

コマンドは、のようないくつかのアクションが動作します。 ExecuteメソッドのCommand1に

は次のように値1にアクセスする:

RequiredData.Value1 = 5 

及びIは、ベースでこれを試み、その後に、Command2に

var k = RequiredData.Value1 //and be 5.. 
or RequiredData.Class1.something = "something" 

ように、この値を持っている方法を実行例えば クラス:

abstract class BaseCommand : ICommand 
    { 
     //or protected and not private... 
     public static RequiredData RequiredData = new RequiredData(); 
    } 

はこのスレッドセーフですか?

ここでスレッドセーフソリューションに必要な変更は何ですか?

+0

'static'は正しい選択ですが、それはすべての派生クラスのすべてのインスタンスで使用されるため、探しているのかどうかは不明です。 –

+0

依存性注入とIoCを使用することを検討してください。これは、通常、より良いアプローチです。 – SLaks

+0

Explain the downvote plz !!!! –

答えて

1

いくつかの方法を使用してこれを解決できます。

  • コンストラクタに共有インスタンスを渡し
  • Singletonパターン/静的には役立ちますが、より制限される可能性があります。

別のスレッドでクラスを使用する場合は、スレッドの安全性に注意する必要があります。


通常は、複数のスレッドで読み込み/書き込み可能な静的オブジェクトは使用しません。私はこれを取り除こうとすることをお勧めします。

しかし、オブジェクト/参照の種類は外部からアクセスできないことを確認する必要があります。

のような:

// you could create the locking in this class, but the class1 property is a 
// reference type, so just locking in the property is not enought, it 
// goes wrong when the Class1 has properties itself. (then these will be 
// altered outside the lock.. 
// I choose to wrap the whole object and only returning value types 

public class RequiredData 
{ 
    public Class1 class1 { get; set; } 
    public int value1 {get; set;} 
} 

abstract class BaseCommand : ICommand 
{ 
    // protected.. should not be accessable from the outside..! 
    protected static RequiredData RequiredData = new RequiredData(); 

    public int GetValue() 
    { 
     lock(RequiredData) 
      return RequiredData.value1; 
    } 

    public void SetValue(int value) 
    { 
     lock(RequiredData) 
      RequiredData.value1 = value; 
    } 

// or you could wrap this in a property 

    public int Value 
    { 
     get { return lock(RequiredData) RequiredData.value1; } 
     set { lock(RequiredData) RequiredData.value1 = value; } 
    } 


    public string GetSomething() 
    { 
     // try to avoid returning reference types, but the can be referenced from outside the object. 
     lock(RequiredData) 
      return RequiredData.Class1.something; 
    } 
} 

ので、ロックはBaseCommand内にある必要があります。また、BaseCommandは、RequiredDataとの通信を担当する必要があります。 (他のオブジェクトがRequiredDataへの参照を持つことはできません)

私が言ったように:マルチスレッド/静的読み取り/書き込みライター=火災で遊んでいます。


多くの読者/ライターがいる場合は、ReaderWriterLock(Slim)をご覧ください。複数のスレッドが同時に読み取ることができ、1つのライターのみがアクティブであるためです。

+0

良いアプローチです。あなたはコードの例を提供することができますか?ありがとう –

+0

私はあなたのような静的なパターンは、大丈夫だと思う。プロパティごとに 'RequiredData'でいくつかのロックが必要です。 –

+0

あなたは私がロッキングの詳細を教えてくれますか?どこに置くことができますか? –

関連する問題