Как удалить все элементы из ConcurrentBag?


Как очистить ConcurrentBag? он не имеет никакого метода, как Clear или RemoveAll...

5 59

5 ответов:

T someItem;
while (!myBag.IsEmpty) 
{
   myBag.TryTake(out someItem);
}

обновление 10/03/2017: Как правильно указывает @Lou, назначение является атомарным. В этом случае, создание ConcurrentBag не будет атомарным, но помещая эту ссылку в переменную будет быть атомарным-так что блокировка или Interlocked.Exchange вокруг него строго не требуется.

дополнительные материалы:

назначение ссылки является атомарным, так почему блокируется.Обмен (ref объект, объект) необходим?

- это ссылка многопотоковое исполнение задания?


вы всегда можете заблокировать доступ к самой сумке и создать новый экземпляр. Предметы в сумке затем будут доступны для GC, если ничто другое не удерживает их:

lock (something)
{
    bag = new ConcurrentBag();
}

или как точки Lukazoid из:

var newBag = new ConcurrentBag();
Interlocked.Exchange<ConcurrentBag>(ref bag, newBag);

простой способ хранения содержимого, однако, это предполагает, что всякий раз, когда элемент хочет получить доступ, он также получает блокировку - это может быть дорого и может свести на нет настройку производительности, которая пошел в ConcurrentBag сам по себе.

если вы знаете, что ничего больше не будет доступа к сумке в это время, крыло-и-молитва его и не запирайте : -)

выбранный ответ, Ну, обходной путь, поэтому я добавляю свой собственный обходной путь.

мое решение было посмотреть на все доступные коллекции в

вы можете удалить объект один за другим в цикле:

object result;
while (bag.TryTake(out result));

обратите внимание, что сумка не гарантируется, чтобы быть пустым после этого цикла, потому что элементы могут быть добавлены после завершения цикла и до следующего оператора другим потоком.

в духе обходных путей.. ConcurrentDictionary<T, bool> имеет атомарный Clear, но также позволяет быстро проверить, если ключ существует. "Быстро" - понятие относительное конечно, но в зависимости от вашего использования, это может быть быстрее, чем перечисление большого стека.