C # Stream Design Вопрос - PullRequest
       11

C # Stream Design Вопрос

1 голос
/ 19 ноября 2009

У меня сейчас есть приложение, которое представляет собой проект трубопровода. На первом этапе он считывает некоторые данные и файлы в поток. Есть несколько промежуточных этапов, которые делают вещи для потока данных. И затем есть заключительная стадия, которая записывает поток куда-то. Все это происходит поочередно, один этап завершается, а затем переходит к следующему этапу.

Все это работало просто замечательно, но теперь объем данных начинает немного увеличиваться (потенциально сотни ГБ). Поэтому я думаю, что мне нужно будет что-то сделать, чтобы облегчить это. Моя первоначальная мысль - это то, что я ищу для обратной связи (будучи независимым разработчиком, мне просто некуда отразить эту идею).

Я думаю о создании параллельного конвейера. Объект, который запускается с конвейера, создает все этапы и запускает каждый в своем собственном потоке. Когда на первом этапе поток достигает некоторого определенного размера, он передает этот поток на следующий этап для обработки и запускает новый собственный поток для продолжения заполнения. Идея заключается в том, что на последнем этапе будут закрываться потоки, так как на первом этапе строятся новые, поэтому использование памяти будет ниже.

Итак, вопросы: 1) Есть мысли высокого уровня о направлениях для этого дизайна? 2) Есть ли более простой подход, который вы можете себе представить, который может применяться здесь? 3) Существует ли что-нибудь, что может сделать что-то подобное, что я мог бы использовать повторно (не продукт, который я должен купить)?

Спасибо

MikeD

Ответы [ 3 ]

1 голос
/ 19 ноября 2009

Модель производителя / потребителя - хороший способ продолжить. И у Microsoft есть свои новые Parallel Extensions , которые должны обеспечить большую часть работы для вас. Посмотрите на объект Task . Для .NET 3.5 / VS2008 доступен предварительный выпуск.

Ваша первая задача должна прочитать блоки данных из вашего потока и затем передать их другим задачам. Затем посередине поставьте столько задач, сколько логически подходит. Меньшие задачи (в общем) лучше. Единственное, на что вам нужно обратить внимание - это убедиться, что последняя задача сохраняет данные в том порядке, в котором они были прочитаны (потому что все задачи в середине могут завершиться в порядке, отличном от того, что они начали).

0 голосов
/ 19 ноября 2009

На каждом этапе вы читаете весь кусок данных, выполняете ли манипуляции, а затем отправляете весь блок на следующий этап?

Если это так, вы используете технику «push», когда вы перемещаете весь кусок данных на следующую стадию. Можете ли вы обрабатывать вещи в более ручье, например, в усадьбе, используя технику «тяги»? Каждый этап является потоком, и когда вы читаете данные из этого потока, он извлекает данные из предыдущего потока, вызывая метод read для него. Когда каждый поток читается, он читает из предыдущего потока маленькими битами, обрабатывает его и возвращает обработанные данные. Целевой поток определяет, сколько байтов нужно прочитать из предыдущего потока, и вам никогда не придется использовать большие объемы памяти. Вот как работают такие приложения, как BizTalk. Есть несколько блогов о том, как работают потоки BizTalk Pipeline, и я думаю, что это может быть именно то, что вы хотите.

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

Часть 1
Часть 2
Часть 3
часть 4
Часть 5

0 голосов
/ 19 ноября 2009

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

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

...