Durumlarda yazma outnumber ölçüde okur ya da (ancak sık) yazıyor bırlıkte verilmemektedir bir, kopya üzerinde yazma yaklaşımı uygun olabilir.
Aşağıda gösterilen uygulama
- lockless
- eşzamanlı değişiklikler devam ederken bile eşzamanlı okumalar için son derece hızlı - ne kadar sürecek olursa olsun
- çünkü "anlık görüntüler" değişmez, kilitsiz atomisite mümkün, yani
var snap = _list; snap[snap.Count - 1];
asla (tabii ki, boş bir liste hariç) atmak asla, ve ayrıca ücretsiz anlık görüntü semantik ile iplik güvenli numaralandırma olsun .. nasıl değişmezlik seviyorum!
- genel olarak uygulanan için, ilgili herhangi bir veri yapısı ve modifikasyon her tür
- Ölü basit , yani testi kolay, hata ayıklama, kodu okuyarak doğrulama
- Net 3.5'te kullanılabilir
Yazarken kopyalamanın işe yaraması için, veri yapılarınızı etkili bir şekilde değişmez tutmalısınız , yani başka iş parçacıkları için kullanılabilir hale getirdikten sonra hiç kimsenin bunları değiştirmesine izin verilmez. Değiştirmek istediğinizde,
- yapıyı klonla
- klonda değişiklik yapma
- değiştirilmiş klon referansında atomik değişim
kod
static class CopyOnWriteSwapper
{
public static void Swap<T>(ref T obj, Func<T, T> cloner, Action<T> op)
where T : class
{
while (true)
{
var objBefore = Volatile.Read(ref obj);
var newObj = cloner(objBefore);
op(newObj);
if (Interlocked.CompareExchange(ref obj, newObj, objBefore) == objBefore)
return;
}
}
}
kullanım
CopyOnWriteSwapper.Swap(ref _myList,
orig => new List<string>(orig),
clone => clone.Add("asdf"));
Daha fazla performansa ihtiyacınız varsa, yöntemin ungenerify edilmesine yardımcı olur, örneğin istediğiniz her değişiklik türü için (Add, Remove, ...) bir yöntem oluşturun ve işlev işaretleyicilerini cloner
ve sabit kodlayın op
.
Not # 1 Hiç kimsenin (sözde) değişmez veri yapısını değiştirmediğinden emin olmak sizin sorumluluğunuzdadır. Bunu önlemek için genel bir uygulamada yapabileceğimiz hiçbir şey yoktur , ancak uzmanlaşırken List.AsReadOnly ()List<T>
kullanarak değişikliklere karşı koruma sağlayabilirsiniz.
Not # 2 Listedeki değerlere dikkat edin. Yukarıdaki yazma yaklaşımı yalnızca liste üyeliğini korur, ancak dizeleri değil, oraya başka değişken nesneleri koyarsanız, iplik güvenliğine dikkat etmelisiniz (örn. Kilitleme). Ancak bu, bu çözüme diktir ve örneğin değişebilir değerlerin kilitlenmesi sorunsuz bir şekilde kullanılabilir. Sadece farkında olmalısın.
Not # 3 Veri yapınız çok büyükse ve onu sık sık değiştiriyorsanız, tümüne yazarken kopyala yaklaşımı hem bellek tüketimi hem de dahil olan kopyalamanın CPU maliyeti açısından engelleyici olabilir. Bu durumda, MS'nin Bağlanabilir Koleksiyonlarını kullanmak isteyebilirsiniz .