Я использую BlockingCollection в сценарии производитель/потребитель, где T — это большие объекты с переменным объемом памяти. Размер некоторых T может достигать 700 МБ, а других — всего 10 МБ. Я хочу установить ограничение на общий объем памяти для всех объектов, которые в любой момент времени хранятся в коллекции. Я не хочу, чтобы объем памяти превышал 1 ГБ, иначе я получу исключение OutOfMemoryException. BlockingCollection не предоставляет эту функциональность «из коробки». Я могу ограничить вместимость коллекции определенным количеством предметов, но не конкретным максимальным общим весом. Поэтому мне, возможно, придется реализовать что-то подобное вручную.
Мой вопрос: как я могу реализовать коллекцию, похожую на BlockingCollection, которая имеет базовые функции, показанные ниже?
Код: Выделить всё
class WeighedBlockingCollection
{
public WeighedBlockingCollection(long maximumTotalWeight);
public void Add(long itemWeight, Func itemFactory);
public void CompleteAdding();
public IEnumerable GetConsumingEnumerable();
}
Метод Add имеет параметр Func itemFactory, поскольку я хочу отложить создание объекта до тех пор, пока в коллекции не будет достаточно пустого места, чтобы принять его. ItemFactory должен вызываться синхронно во время вызова Add (т. е. он должен вызываться производителем, а не потребителем). В остальном коллекция должна вести себя точно так же, как встроенная BlockingCollection. Он должен быть потокобезопасным и поддерживать несколько производителей и потребителей.
При наличии нескольких производителей значение Add должно быть примерно в порядке FIFO. Он
не отдает приоритет объектам меньшего размера по сравнению с объектами большего размера.
В случае, если Add вызывается с itemWeight, большим, чем указанный MaximumTotalWeight, или отрицательным, должно быть выдано исключение.
Примечание: Этот вопрос надуманный. Это было вдохновлено недавним вопросом.
Подробнее здесь:
https://stackoverflow.com/questions/796 ... d-capacity