Я читал о новых параллельных коллекциях, и особенно ConcurrentBag привлек мое внимание.Поскольку ConcurrentBag внутренне содержит локальный набор в каждом отдельном потоке, используя его для отслеживания элементов, это означает, что когда сам поток выходит из области видимости, он все равно будет ссылаться в памяти ConcurrentBag.Это в свою очередь означает как память, заявленную потоком, так и собственные ресурсы?(извините, что не знаете точную внутреннюю работу объекта потока .NET)
Я могу предположить, что у вас есть 1 глобальный ConcurrentBack для многопоточного веб-сервиса, где у вас много клиентов, добавляющих задачи.Эти задачи добавляются потоками в пул потоков.Теперь пул потоков - очень эффективный способ управления потоками, но он действительно удаляет и создает потоки в зависимости от объема работы.Поэтому такой веб-сервис иногда может оказаться в затруднительном положении, поскольку основная сумка все еще ссылается на многие подлежащие уничтожению потоки.
Я создал быстрое приложение для проверки этого поведения:
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();
И вывод подтверждает мою историю:
Bag size is: 0
Bag size is: 100
Bag size is: 200
Bag size is: 200
Remote thread still exists
Bag size is: 200
Можно ли ожидать такого поведения, допустил ли я ошибку в своем тесте или это можно считать недостатком дизайна?