2010-12-03 41 views
1

Je construis un éditeur de glisser-déposer basé sur un nœud, où chaque nœud représente une action (par exemple, lire ce fichier, ou trier ces données, etc.) Les sorties et les entrées des nœuds peuvent être connecté.Stratégies pour la parallélisation automatique

L'une des fonctionnalités que je voudrais mettre en œuvre est automatic parallelization, de sorte que si un chemin bifurque je peux automatiquement commencer un thread pour gérer chaque branche. Je suis préoccupé par quelques problèmes, cependant:

  • Si un chemin bifurque, mais se joint plus tard revenir ensemble, je aurai besoin de les synchroniser en quelque sorte
  • Si plusieurs start-noeuds (où l'exécution commence), leurs chemins devront être gérés séparément, puis peut-être dynamiquement rejoint/fusionné
  • Je veux limiter le nombre de threads sont créés pour que je n'ai pas soudainement 20 fils dans l'impasse

Essentiellement, je aimerais savoir si des stratégies pour faire quelque chose comme ça ex ist (ne cherche pas nécessairement le code; juste la théorie). Des algorithmes d'ordonnancement pourraient-ils aider?

Merci pour votre conseils! J'ai hâte d'entendre vos suggestions.

Note: J'utilise C# 3.5, donc aucune des capacités amusantes de tâches parallèles n'est disponible pour moi. Si nécessaire, je vais passer à C# 4.0, mais je voudrais éviter cela.

Répondre

3

Le Task Parallel Library peut être exactement ce que vous cherchez.

J'imagine votre éditeur glisser-déposer à base de nœud à ressembler à ceci:

 

      Illustration

 

Chaque noeud est essentiellement un Task. Une tâche peut être n'importe quoi - lire un fichier à partir d'un disque, télécharger des données sur le Web ou tout calculer.

Lorsqu'une tâche est terminée, elle peut continuer avec une ou plusieurs autres tâches, en transmettant le résultat de l'ancienne tâche aux nouvelles tâches.

Une tâche peut également consister à attendre la fin de plusieurs tâches. Lorsque toutes les tâches ont terminé, cette tâche peut continuer avec une autre tâche, en transmettant le résultat de toutes les tâches à la nouvelle tâche.

Le TPL planifie toutes ces tâches sur un pool de threads, de sorte que les threads peuvent être réutilisés et chaque tâche n'a pas besoin d'avoir son propre thread. Le TPL trouvera le nombre optimal de Threads pour le système sur lequel il s'exécute.

Le Visual Studio Async CTP ajoute la prise en charge du langage natif pour les opérations asynchrones en C#, ce qui rend le travail avec les tâches très facile et amusant.Avec le TPL, il suffit de créer des tâches et de les composer en fonction de la disposition des nœuds.

code de programme complet pour l'exemple ci-dessus:

var t1 = Task.Factory.StartNew<int>(() => 42); 

var t2a = t1.ContinueWith<int>(t => t.Result + 1); 
var t2b = t1.ContinueWith<int>(t => t.Result + 1); 

var t3a = t2a.ContinueWith<int>(t => t.Result * 2); 
var t3b = t2b.ContinueWith<int>(t => t.Result * 3); 

var t4 = TaskEx.WhenAll<int>(t3a, t3b) 
       .ContinueWith<int>(t => t.Result[0] + t.Result[1]); 

t4.ContinueWith(t => { Console.WriteLine(t.Result); }); 

Console.ReadKey(); 
+2

+1 Vous pouvez également contrôler le nombre de threads que vous voulez utiliser en écrivant votre propre TaskScheduler et il y a beaucoup d'autres points d'extension de la bibliothèque. –

+0

Merci pour ce dtb et Hightechrider, on dirait que ce sera très utile –