ConcurrentBag - Добавить несколько элементов?

Есть ли способ добавить несколько элементов в ConcurrentBag одновременно, а не по одному? Я не вижу метода AddRange () в ConcurrentBag, но есть Concat (). Однако это не работает для меня:

<code>ConcurrentBag<T> objectList = new ConcurrentBag<T>();

timeChunks.ForEach(timeChunk =>
{
    List<T> newList = Foo.SomeMethod<T>(x => x.SomeReadTime > timeChunk.StartTime);
    objectList.Concat<T>(newList);
});
</code>

Этот код раньше был в Parallel.ForEach (), но я изменил его на вышеприведенный, чтобы я мог устранить его. Переменная newList действительно имеет объекты, но после objectList.Concat & lt; & gt; В строке objectList всегда содержится 0 объектов. Является ли Concat & lt; & gt; не так работать? Нужно ли добавлять элементы в ConcurrentBag по одному с помощью метода Add ()?

Ответы на вопрос(4)

(Я знаю, что это старый пост, подумал, я бы кое-что добавил).

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

    public static void AddRange<T>(this ConcurrentBag<T> @this, IEnumerable<T> toAdd)
    {
        foreach (var element in toAdd)
        {
            @this.Add(element);
        }
    }

А потом:

    ConcurrentBag<int> ccBag = new ConcurrentBag<int>();
    var listOfThings = new List<int>() { 1, 2, 4, 5, 6, 7, 8, 9 };
    ccBag.AddRange(listOfThings);

Я также рассмотрел использование AsParallel для добавления в метод расширения, но после запуска некоторых тестов по добавлению списка строк различных размеров было значительно медленнее использовать AsParallel (как показано здесь) в отличие от традиционного цикла for.

    public static void AddRange<T>(this ConcurrentBag<T> @this, IEnumerable<T> toAdd)
    {
        toAdd.AsParallel().ForAll(t => @this.Add(t));
    }

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

Вам нужно будет добавить свои предметы вConcurrentBag один за раз.

Решение Вопроса

Да :)

Concat возможно, один изEnumerable расширения. Это ничего не добавляет кConcurrentBag, он просто возвращает какой-то забавный объект, содержащий оригинальную сумку и все, что вы пытались добавить туда.

Остерегайтесь того, что результатConcat это неConcurrentBag больше, так что вы не хотели бы использовать его. Это часть общей структуры LINQ, позволяющая комбинировать неизменяемые последовательности. Эта структура, конечно, не пытается расширять параллельные свойства операндов до результата, поэтому результирующий объект не будет так хорошо подходить для многопоточного доступа.

(В принципе,Concat относится кConcurrentBag потому что это разоблачаетIEnumerable<T> интерфейс.)

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

Как сказал Влад, объединение одновременного пакета со списком типов объектов не возвращает параллельный пакет, поэтому concat не сработает! (Мне потребовалось некоторое время, чтобы понять, что я не могу этого сделать.)

Попробуйте вместо этого - создайтеList<T>, а затем создатьConcurrentBag<List<T>>, На каждой параллельной итерации будет добавляться новый список в параллельный пакет. Когда параллельный цикл завершен, переберитеConcurrentBag и concat (или union, если вы хотите исключить возможные дубликаты) до первогоList<T> что вы создали, чтобы "сгладить" все в один список.

 08 февр. 2018 г., 18:06
Чтобы сгладить, используйте SelectMany в конце.

Ваш ответ на вопрос