.NET

2010-06-05 30 views
63

'daki güvenli koleksiyonları iş parçacığı Güvenli bir koleksiyona (örneğin, Set) ihtiyaç duyulduğunda günümüzde standart nedir. Bunu kendim mi senkronize edebilirim veya dahili olarak güvenli bir koleksiyon var mı?.NET

+6

Hangi operasyonlar için güvenlidir? –

+2

@John, bildiğiniz gibi, ekleyerek, okuyorsunuz… java'nın eşzamanlı koleksiyonları gibi bir şey. – ripper234

+1

Sorunuzu bu bilgilerle güncellemeniz gerekir. Her şey için iş parçacığı güvenli olan koleksiyonlar, örneğin, yalnızca insert eklemek için güvenli bir koleksiyona sahip olmak istediğiniz büyük bir fark yaratır. –

cevap

94

.NET 4.0 Framework System.Collections.Concurrent Namespace birkaç evreli koleksiyonlarını tanıttı:

ConcurrentBag<T>
      nesnelerin evreli, sırasız koleksiyon temsil eder.

ConcurrentDictionary<TKey, TValue>
   

aynı anda birden fazla parçacığı tarafından erişilebilen bir anahtar değer çiftleri evreli toplama temsil eder.

ConcurrentQueue<T>
   

bir evreli ilk giren ilk çıkar (FIFO) koleksiyonunu temsil eder.

ConcurrentStack<T>
   

giren ilk çıkar (LIFO) koleksiyon evreli sondan temsil eder. .NET Framework içinde


Diğer koleksiyonlar-iplik güvenli varsayılan olarak ve her operasyon için kilitlenmesi gerektiğini değildir:

lock (mySet) 
{ 
    mySet.Add("Hello World"); 
} 
+3

İplik güvenli bir koleksiyon oluştururken ReaderWriterLockSlim kullanmayı tercih edebilirsiniz. – SandRock

4

.NET 4 evreli koleksiyonları kümesi sağlar System.Collections.Concurrent

17

Pre. Net 4.0 altında .Net koleksiyonlarının çoğunda thread güvenli değil.

Koleksiyonlar sınıflar yapılabilir güvenli iplik aşağıdaki yöntemlerden birini kullanarak:

oluştur makaleden http://msdn.microsoft.com/en-us/library/573ths2x.aspx

Alıntı: Sen senkronizasyonu işlemek için bazı işler kendiniz yapmak gerekecek Senkronize yöntemini kullanarak bir iş parçacığı güvenli sarıcı kullanın ve koleksiyonuna yalnızca bu sarıcısından erişin.

sınıf bir Senkronize yöntem yoksa

, sınıftan türetmek ve SyncRoot özelliğini kullanarak Senkronize yöntemi uygulamak. koleksiyonunu erişirken

SyncRoot mülkiyet, C# ( Visual Basic SyncLock) içinde kilit ifadesi olarak, bir kilitleme mekanizması kullanın. Sync Root Property
olarak Lock Statement

Object thisLock = new Object(); 
...... 
lock (thisLock) 
{ 
    // Critical code section 
} 

.4.0 net System.Collections.Concurrent ad

Blocking Collection
Concurrent Bag
Concurrent Queue
Concurrent Dictionary
Ordable Partitioner
System.Collections.Concurrent çok yararlı sınıflar için bir ek olarak Partitioner
Partitioner T

+4

Kilitlemekte olduğunuz nesne bir örnek değişkeni olmalıdır, aksi halde mantıklı değildir çünkü her zaman yeni bir referansı kilitlersiniz. – Femaref

+1

Bu doğru. Bu, Kilit kodunun kullanıldığı MSDN sayfasında bulunan bir örnektir. – kemiller2002

1

, çoğunlukla bir standart teknik, kişiye -de-nadiren-değişim sc Enarios (ya da ancak sık, ama eşzamanlı olmayan yazıyorsa). Net için de geçerlidir. Copy-on-write denir.

Oldukça-eşzamanlı programlarda arzulanan özellikleri bir çift vardır

: kendilerini değişmez (yani evreli, güvenli kilitleme olmadan sayılabilir) olan

  • toplama nesne örnekleri
  • modifikasyonunu alabilir o, performans ve
karşımı bir iş parçacığı için güvenli olmayan herhangi bir veri yapısını açmak için implemented generically olabilir etkilenmez okur ait eşzamanlılık istediği kadar zaman

Sınırlama: Eşzamanlı yazımlar varsa, değişikliklerin yeniden denenmesi gerekebilir, bu nedenle daha fazla yazılan yazma sayısı o kadar az olur. (Yani işte optimistic concurrency var)

Düzenleme Scott Chamberlain'in comment orada başka sınırlama olduğunu hatırlattı: Veri yapıları çok büyük değilse ve modifikasyonlar bir kopyası-hepsi üzerinde yazma açısından hem yasaklayıcı olabilir, sık sık meydana hafıza tüketimi ve kopyalamanın CPU maliyeti dahil.

+0

Microsoft, [Microsoft.Bcl.Immutable] (https://www.nuget.org/packages/Microsoft.Bcl.Immutable) aracılığıyla, NuGet aracılığıyla bir dizi yazıştırma koleksiyonları sağlar. Daha fazla bilgi bulabilirsiniz. (http://blogs.msdn.com/b/bclteam/archive/2012/12/18/preview-of-immutable-collections-released-on-nuget.aspx) –

+0

@ScottChamberlain Theirs basitliğimden çok daha karmaşıktır ancak jenerik, "yazının tümünü kopyala" yaklaşımı, verilerin yalnızca bir kısmını kopyaladıkları için. Bu nedenle, her ikisi de kopyalamanın CPU maliyeti ve bellekte birden fazla tam kopya tutmanın bellek tüketimi açısından, herşeyi bir arada kopyalama ile etkisiz olacak olan büyük veri yapılarını bile değiştirebilirler. –