ConcurrentBag
Nasıl Temizlenir? Bunu bir döngü içinde teker nesneyi tek kaldırabilirsinizConcurrentBag'den tüm öğeler nasıl kaldırılır?
cevap
T someItem;
while (!myBag.IsEmpty)
{
myBag.TryTake(out someItem);
}
adresini okumak isteyebilirsiniz. Bu kesinlikle atomik değil. Yani diğer yöntemlerin atomik erişim varsayımı ile kullanıldığı gibi, ConcurrentBag üzerinde bir uzatma yöntemi olarak eklenmemelidir. – Anupam
Ayrıca, boş bırakılmasının yanı sıra başka nedenlerle de başarısız olabilirsiniz? – BrainSlugs83
Bu çok tehlikelidir. Başka bir işlem sürekli olarak öğeler ekliyorsa, bu meşgul kalabilir. – IvoTops
... Clear
veya RemoveAll
gibi herhangi bir yöntem yoktur:
object result;
while (bag.TryTake(out result));
Not Döngü, öğeler bittikten sonra öğeler eklenebilir ve farklı iş parçacığı tarafından sonraki deyimden önce.
Evet .. Aynı hatayla karşılaşıyorum. Bir iş parçacığı aynı anda onu temizlemeye çalışıyor ... böylece boş bir çanta yok ... – PawanS
Bu aynı nedenden dolayı yanlış kabul edilen cevap yanlıştır. –
Güncelleme 10/03/2017: @ @ Doğru şekilde işaret ettiyseniz, atama atomiktir. Bu örnekte, ConcurrentBag
'un oluşturulması atomik olmayacaktır, ancak bu referansı atomik atomuna sokacaktır - bu yüzden kilitleme veya Interlocked.Exchange
kesinlikle gerekli değildir.
Bazı ileri okuma:
reference assignment is atomic so why is Interlocked.Exchange(ref Object, Object) needed?
Is a reference assignment threadsafe?
Bunun yeni bir örneğini her zaman kilit çanta kendisine erişim ve yaratabilir. başka hiçbir şey onlara tutunarak ise torba içinde Öğeler sonra GC için uygun hale gelmeden olacaktır:
lock (something)
{
bag = new ConcurrentBag();
}
Veya Lukazoid işaret ettiği gibi: bin
var newBag = new ConcurrentBag();
Interlocked.Exchange<ConcurrentBag>(ref bag, newBag);
Kolay yolu içerikleri, ancak bu varsayar Bir öğe erişim istediğinde de kilidi alır - bu pahalı olabilir ve ConcurrentBag
'un kendisine giden performans ayarını olumsuz etkileyebilir.
Eğer başka bir şey bu kez, kanat-and-a-namaz it at çantayı erişecek ve
Torbayı her hangi bir yerde kullanmanızın bir kopyasını almak için daha iyi bir çözüm olmaz mıydı, o zaman sadece 'bag = new' cezasız kalabilirsiniz? –
@ChrisMarisic Evet, verileri paylaşmaktan kaçınabiliyorsanız, bu sorunlardan kurtuldunuz. Ancak sorunun çok fazla bağlamı yoktu. –
'Interlocked.Exchange' bir kilitden daha iyi olabilir – Lukazoid
:-) kilitlenmesini engellemek için biliyorsanız seçilen cevap tür, iyi, bir geçici çözüm, bu yüzden kendi çözümümü ekliyorum.
Çözümüm, koleksiyondaki tüm öğeleri temizlemenin önemsiz olduğunu bulmak için System.Collections.Concurrent ad alanındaki tüm kullanılabilir koleksiyonlara bakmaktı.
ConcurrentStack sınıfı, koleksiyondaki tüm öğeleri kaldıran Clear() yöntemine sahiptir. Aslında, isim alanında (şu anda) bulunan tek koleksiyon. Evet, Add(T element)
yerine Push(T element)
'a ihtiyacınız var, ama açıkçası bu zaman kazandı.
Yine de koleksiyonlar arasında başka önemli farklılıklar var. Örneğin, belirli bir öğenin koleksiyonda olup olmadığını belirlemeniz gerekiyorsa, hem bir Çanta ile hem de bir Yığın ile değil, hem önemsiz hem de etkilidir. – Servy
@Servy: Evet ama hala. Hayır, aslında bir pro/con listesi yazmaya başladım, ama gerçekten ihtiyaçlarınızın ne olduğuna bağlı. Örneğin, eşzamanlı koleksiyonlar çok iş parçacıklı erişim için iyidir, ancak bunların hiçbiri bunları kullanmanıza engel olabilecek bir şeyleri koleksiyonunuza dizine eklemenize izin vermez. Soru, özellikle eşzamanlı bir torbayı temizlemekti (bu yüzden ona rastladım), ve koleksiyonun iplik güvenliği ile önemsiz bir şekilde temizlenmesi benim ihtiyacımdı. Cevabım koleksiyonları değiştirmekti. – Will
Ayrıca çanta yerine eşzamanlı yığın kullanıyorum. Bu yığının Clear ve Bag içermemesi garip. Torbanın ana amacı değerleri saklamak, varlığı kontrol etmek ve tek veya hepsini kaldırmaktır. Eşzamanlı yığın "biraz sınırlı gerçek eşzamanlı çanta" benzer bir şey olur. – Maxim
Çözümlerin ruhunda .. ConcurrentDictionary<T, bool>
bir atomik Clear'e sahip, ancak bir anahtar olup olmadığını hızlı bir şekilde kontrol etmenizi de sağlar. 'Çabuk' tabiki göreceli bir terimdir, fakat kullanımınıza bağlı olarak büyük bir yığının numaralandırılmasından daha hızlı olabilir.
Bu https://social.msdn.microsoft.com/Forums/en-US/accf4254-ee81-4059-9251-619bc6bbeadf/clear-a-concurrentqueue?forum=rx –