2016-08-09 8 views
7

をコピーせずにリストにアクセスを読むには、次の例を考えてみましょうか? C#には同時のCollectionsがありますが、スレッドセーフリストはありません。 JavaではCopyOnWriteArrayListのようなものがあります。C#の並列は

+5

方法について 'ImmutableList '](https://msdn.microsoft.com/ 「System.Collections.Immutable」パッケージのen-us/library/dn467185(v =対111).aspx) –

+0

ブロックコレクションについてはどうですか? (https://msdn.microsoft.com/en-us/library/dd267312(v=vs.110).aspx) – derape

+0

他のコード(おそらく別のスレッド)が呼び出されている間に 'ModifyOperation() 'Contents'から返されたオブジェクトへのアクセス権を持っていれば、コピーしないで' List 'を返すとスレッドセーフではなくなります。 –

答えて

6

私の意見ではからImmutableList<T>クラスからこのようなシナリオにはパッケージが最適です。それはIReadOnlyList<T>を実装しており、変更できない、つまり変更されていないため、読み取りアクセッサから直接返すことができます。変更操作の間になり、必要なときだけ同期:

class Example 
{ 
    private ImmutableList<string> _list = ImmutableList<string>.Empty; 
    private readonly object _lock = new object(); 

    public IReadOnlyList<string> Contents => _list; 

    public void ModifyOperation(string example) 
    { 
     lock (_lock) 
     { 
      // ... 
      _list = _list.Add(example); 
      // ... 
     } 
    } 
} 
1

ロックフリーの提案...

class Example 
{ 
    private ImmutableList<String> _list = ImmutableList<String>.Empty; 

    public IReadOnlyList<String> Contents { get { return _list; } } 

    public void ModifyOperation(String example) 
    { 
     ImmutableList<String> original; 
     ImmutableList<String> afterChange; 
     do 
     { 
      original = _list; 
      afterChange = _list.Add(example); 
     } 
     while (Interlocked.CompareExchange(ref _list, afterChange, original) != original); 
    } 
} 
+0

非常に良い。ありがとう! – Nico