Yeni eş zamanlı koleksiyonları okudum ve özellikle ConcurrentBag dikkatimi çekti. ConcurrentBag, öğeleri takip etmek için her bir iş parçacığı üzerinde yerel bir kümeyi dahili olarak tuttuğundan, bu, iş parçacığının kendisi kapsam dışına çıktığında, ConcurrentBag tarafından bellekte referans alınacağı anlamına gelir. Bu da, iş parçacığı tarafından talep edilen bellek, hem de yerel kaynaklar anlamına gelir? (.NET iş parçacığının tam iç işleyişini bilmediğim için özür dilerim)ConcurrentBag içinde olası ezbere?
Birden çok iş parçacığına sahip bir web hizmetinde, görevler ekleyen çok sayıda istemci hizmeti için 1 global ConcurrentBack'inizin bulunduğu bir kullanıcı hesabı alabiliyorum. Bu görevler iş parçacığı üzerinde iş parçacıkları tarafından eklenir. Artık iş parçacığı, iş parçacıklarını yönetmek için çok etkili bir yoldur, ancak iş miktarına bağlı olarak iş parçacıklarını kaldırır ve oluşturur. Bu nedenle, böyle bir web servisi, zaman zaman, altta yatan torbanın hala tahrip olmuş bir çok dişe atıfta bulunmasından ötürü zaman zaman kendini sorunlu bulabilir.
Ben bu davranışı test etmek için hızlı bir uygulamayı yarattı:static ConcurrentBag<int> bag = new ConcurrentBag<int>();
static void FillBag() { for (int i = 0; i < 100; i++) { bag.Add(i); } }
static void PrintState() { Console.WriteLine("Bag size is: {0}", bag.Count); }
static void Main(string[] args)
{
var remote = new Thread(x =>
{
FillBag();
PrintState();
});
// empty bag
PrintState();
// first 100 items are added on main thread
FillBag();
PrintState();
// second 100 items are added on remote thread
remote.Start();
remote.Join();
// since the remote thread is gone out of scope, what happened to its local storage which is part of the bag?
PrintState();
// now force a cleanup
WeakReference weakRemoteReference = new WeakReference(remote);
remote = null;
GC.Collect();
GC.WaitForPendingFinalizers();
// Now check if the thread still exists
if (weakRemoteReference.IsAlive)
Console.WriteLine("Remote thread still exists");
PrintState();
Console.ReadLine();
Ve çıkış öykümü doğruluyor:
Bag size is: 0
Bag size is: 100
Bag size is: 200
Bag size is: 200
Remote thread still exists
Bag size is: 200
beklenen bu davranış mı benim testinde bir hata yaptın ya da bu tasarım hatası olarak düşünülebilir mi?
Uzaktaki iş parçacığının, kapsam dışında kaldığını varsayarım, bunun hala kapsamda olduğunu ve şunu söylemelidir: "Uzak iş parçacığı bittiğinden" – Polity