2010-01-04 8 views
3

J'ai récemment commencé à travailler sur une nouvelle application qui utilisera le parallélisme des tâches. Je viens de commencer à écrire un cadre de tâches, mais j'ai récemment vu un certain nombre de messages sur SO concernant le nouvel espace de noms System.Threading.Tasks qui peut m'être utile (et je préfère utiliser un framework existant plutôt que le mien)..NET 4.0 Threading.Tasks

recherche sur MSDN Cependant, je ne l'ai pas vu comment/si, je peux mettre en œuvre la fonctionnalité que je suis à la recherche:

  • dépendance à d'autres tâches complétant.
  • Capable d'attendre sur un nombre inconnu de tâches préformage la même action (peut-être enveloppé dans le même objet task qui est invoqué plusieurs fois)
  • Définir instances simultanées maximum d'une tâche car ils utilisent une ressource partagée il n'y a pas de point courir plus d'un à la fois
  • Conseil à priorité ou planificateur met tâches avec des instances simultanées maximales inférieures à une priorité plus élevée (de manière à maintenir ladite ressource en cours d'utilisation autant que possible)
  • Modifier possibilité de faire varier la priorité des tâches qui préforment la même action (assez mauvais exemple mais, PredictWeather (Tommorrow) aura un p Plus que PredictWeather (NextWeek))

Quelqu'un peut-il me diriger vers un exemple/dites-moi comment je peux y parvenir? À votre santé.

C# Cas d'utilisation: (tapés en SO donc s'il vous plaît pour donner des erreurs de syntaxe/fautes de frappe)

** Note Do()/DoAfter() ne doit pas bloquer le thread appelant *

class Application() 
{ 

    Task LeafTask = new Task (LeafWork) {PriorityHint = High, MaxConcurrent = 1}; 
    var Tree = new TaskTree (LeafTask); 

    Task TraverseTask = new Task (Tree.Traverse); 
    Task WorkTask = new Task (MoreWork); 
    Task RunTask = new Task (Run); 

    Object SharedLeafWorkObject = new Object(); 

    void Entry() 
    { 
     RunTask.Do(); 
     RunTask.Join(); // Use this thread for task processing until all invocations of RunTask are complete 
    } 

    void Run(){       
     TraverseTask.Do(); 

     // Wait for TraverseTask to make sure all leaf tasks are invoked before waiting on them 
     WorkTask.DoAfter (new [] {TraverseTask, LeafTask}); 

     if (running){ 
      RunTask.DoAfter (WorkTask); // Keep at least one RunTask alive to prevent Join from 'unblocking' 
     } 
     else  
     { 
      TraverseTask.Join(); 
      WorkTask.Join(); 
     } 
    } 

    void LeafWork (Object leaf){ 
     lock (SharedLeafWorkObject) // Fake a shared resource 
     { 
      Thread.Sleep (200); // 'work' 
     } 
    } 

    void MoreWork() 
    { 
     Thread.Sleep (2000); // this one takes a while 
    } 
} 


class TaskTreeNode<TItem> 
{ 
    Task LeafTask; // = Application::LeafTask 
    TItem Item; 

    void Traverse() 
    { 
     if (isLeaf) 
     { 
      // LeafTask set in C-Tor or elsewhere 
      LeafTask.Do(this.Item); 

      //Edit 
      //LeafTask.Do(this.Item, this.Depth); // Deeper items get higher priority 
      return; 
     } 
     foreach (var child in this.children) 
     { 
      child.Traverse(); 
     } 
    } 
} 

Répondre

4

Il Les exemples sont nombreux ici:

http://code.msdn.microsoft.com/ParExtSamples

Il y a un grand livre blanc qui couvre beaucoup de détails, vous mentionnez ci-dessus ici:

« Modèles de programmation parallèle: Comprendre et appliquer des motifs parallèles avec le .NET Framework 4 »

http://www.microsoft.com/downloads/details.aspx?FamilyID=86b3d32b-ad26-4bb8-a3ae-c1637026c3ee&displaylang=en

Off Au sommet de ma tête, je pense que vous pouvez faire toutes les choses que vous énumérez dans votre question.

  • etc: Dépendances Task.WaitAll (Tâche [] tâches)
  • Scheduler: La bibliothèque prend en charge de nombreuses options pour limiter nombre de threads utilisés et prend en charge de fournir votre propre planificateur. J'éviterais de modifier la priorité des threads si cela est possible. Cela risque d'avoir un impact négatif sur le planificateur, sauf si vous fournissez le vôtre.