Имеется большой массив данных, который обрабатывается несколькими потоками одновременно (сами элементы массива не изменяются, а лишь читаются). Необходимо реализовать функционал, который позволяет равномерно распределить работу: у каждого потока в любой момент времени есть 1 обрабатываемый элемент, завершив работу с этим элементом, вызывается метод GetItem(), который запрашивает следующий элемент. Как идея: создать внутренний словарь где ключом будет идентификатор потока, а значением - позиция обрабатываемого элемента. При вызове метода GetItem() осуществляется потокобезопасный поиск номера элемента, который может быть следующим (номер на единицу больше наибольшего из номеров, обрабатываемых в настоящий момент, либо наименьший номер находящий между соседними отсортированными по возрастанию номерами с разницей больше 1). Так же следует избежать копирования самого массива - необходимо лишь вытаскивать в нужный момент элемент с определённым номером.
Просто разделить весь массив на несколько равных по размеру сегментов и скормить соответствующему количеству потоков не подходит, так как время обработки каждого элемента может сильно отличаться, и в то время как один поток завершит обработку, другие будут простаивать.
UPD: Работа всех потоков может быть прервана и тогда важно сохранить номера обрабатываемых элементов, чтобы в следующий раз можно было с них же начать.
BlockingCollectingизбегая копирования элементов? Мне кажется нет. Дополнил вопрос. – D .Stark Sep 23 '22 at 09:39ConcurrentQueue. При остановке работы можно запомнить оставшееся количество элементов (вычитая из общего количества элементов получим значение числа элементов, которые нужно отсечь с начала массива при возобновлении работы). "Не понял про копирование." - исходный массив очень большой по размеру, при создании того же экземпляраConcurrentQueueв конструктор передаётсяIEnumerable- произойдёт ли копирования элементов в какую-нибудь внутреннюю коллекцию? То есть не хотелось бы иметь в памяти 2 одинаковых больших набора данных. – D .Stark Sep 23 '22 at 11:47Segment, который, я полагаю, похож наArraySegmentи не содержит самих элементов, а лишь указывает на сегмент исходной коллекции. – D .Stark Sep 23 '22 at 11:50ArraySegmentк примеру не хранит ни ссылок ни самих элементов. – D .Stark Sep 24 '22 at 13:52