2009-11-19 9 views
1

J'ai une application en ce moment qui est une conception de pipeline. Dans une première étape, il lit des données et des fichiers dans un flux. Il y a des étapes intermédiaires qui font des choses dans le flux de données. Et puis il y a une dernière étape qui écrit le flux vers quelque part. Tout se passe en série, une étape se termine et passe ensuite à l'étape suivante.C# Stream Design Question

Tout cela a très bien fonctionné, mais maintenant la quantité de données commence à devenir un peu plus importante (des centaines de Go potentiellement). Donc je pense que je vais devoir faire quelque chose pour atténuer cela. Ma première idée est de savoir ce que je cherche sur ce point (étant un développeur indépendant, je n'ai pas d'endroit pour faire de l'idée). Je pense à créer un pipeline Parallel. L'objet qui commence le pipeline créerait toutes les étapes et kick chacune dans son propre fil. Lorsque la première étape mettra le flux à une certaine taille, il passera ce flux à l'étape suivante pour le traitement et démarrera un nouveau flux pour continuer à se remplir. L'idée ici étant que la dernière étape sera la fermeture des flux comme la première étape est la construction d'un nouveau afin que mon utilisation de la mémoire serait maintenue plus bas.

Donc, des questions: 1) Des pensées de haut niveau sur les directions pour cette conception? 2) Y a-t-il une approche plus simple à laquelle vous pouvez penser et qui pourrait s'appliquer ici? 3) Existe-t-il quelque chose qui existe déjà et que je puisse réutiliser (pas un produit que je dois acheter)?

Merci,

MikeD

Répondre

1

Le modèle producteur/consommateur est une bonne façon de procéder. Et Microsoft a leur nouveau Parallel Extensions qui devrait fournir la plupart du travail de terrain pour vous. Regardez dans l'objet Task. Il existe une version de prévisualisation disponible pour .NET 3.5/VS2008.

Votre première tâche devrait lire les blocs de données de votre flux, puis les transmettre à d'autres tâches. Ensuite, ayez autant de tâches au milieu que logiquement. Les tâches plus petites sont (généralement) meilleures. La seule chose à surveiller est de s'assurer que la dernière tâche enregistre les données dans l'ordre où elles ont été lues (car toutes les tâches du milieu peuvent finir dans un ordre différent de ce qu'elles ont commencé).

+0

Les extensions parallèles semble très prometteur. Je pense que je peux créer une tâche pour chaque étape, démarrer chaque étape et utiliser les nouvelles classes de collection simultanée pour passer les flux entre les étapes. Je ne voulais pas vraiment utiliser VS 2010, et je n'arrive plus à trouver la version preview. Je vais continuer à regarder. – MikeD

+0

Le lien de téléchargement pour l'aperçu est ci-dessous, mais MS semble avoir changé de site Web et le lien ne fonctionne plus :-( http://www.microsoft.com/downloads/details.aspx?FamilyId=348F73FD -593D-4B3C-B055-694C50D2B0F3 – ligos

0

Pour la conception que vous avez dit, vous voulez avoir une bonne lecture sur producer/consumer problems si vous avez pas déjà. Vous aurez besoin d'une bonne compréhension de l'utilisation des sémaphores dans cette situation.

Une autre approche que vous pouvez essayer est de créer plusieurs pipelines identiques, chacun dans un fil séparé. Cela serait probablement plus facile à coder car il y a beaucoup moins de communication inter-thread. Toutefois, en fonction de vos données, vous ne pourrez peut-être pas les diviser en plusieurs parties de cette façon.

0

A chaque étape, lisez-vous l'ensemble des données, effectuez la manipulation, puis envoyez le mandrin entier à l'étape suivante?

Si c'est le cas, vous utilisez une technique de «push» où vous poussez l'ensemble du bloc de données à l'étape suivante. Êtes-vous capable de gérer les choses dans un ruisseau plus comme manoir en utilisant une technique de "tirer"? Chaque étape est un flux et, lorsque vous lisez les données de ce flux, il extrait les données du flux précédent en appelant read sur celui-ci. À mesure que chaque flux est lu, il lit le flux précédent en petits bits, le traite et renvoie les données traitées. Le flux de destination détermine le nombre d'octets à lire dans le flux précédent et vous n'avez jamais besoin de consommer de grandes quantités de mémoire. C'est ainsi que fonctionnent les applications comme BizTalk.Il existe des blogs sur le fonctionnement des flux BizTalk Pipeline, et je pense que c'est peut-être exactement ce que vous voulez.

Voici une entrée de blog en plusieurs parties qui pourraient vous intéresser:

Part 1
Part 2
Part 3
Part 4
Part 5

+0

Euhhh, pourquoi le downvote? Quel est le problème avec cette réponse? – Jeremy