2 Stimmen

Eine gute Möglichkeit, immer 10 TPL-Aufgaben laufen zu lassen und eine neue zu starten, wenn eine abgeschlossen ist, in einer Schleife?

Ich habe eine Winform-Anwendung und lerne gerade TPL für die parallele Programmierung. Die WinForm läuft kontinuierlich und spidert 10 Websites gleichzeitig. Jede Website wird von einer TPL-Aufgabe bearbeitet. Die Aufgaben sind unabhängig voneinander. Jedes Mal, wenn eine Aufgabe erledigt ist, wird eine neue Aufgabe gestartet. Ich beabsichtige, Task.Factory.StartNew(..) für das Starten von Aufgaben zu verwenden.

Ich bin mit dem Starten von TPL-Aufgaben vertraut, aber ich verstehe nicht, wie man mehrere TPL-Aufgaben gleichzeitig in einer Schleife startet und jedes Mal, wenn eine Aufgabe abgeschlossen ist, eine neue startet, so dass effektiv immer 10 Aufgaben laufen.

Wie kann ich das tun?

2voto

Drew Marsh Punkte 32833

Wenn Sie eine Liste von z.B. 1000 URLs haben, aber nicht mehr als 10 gleichzeitig verarbeiten wollen, ist die einfachste Möglichkeit, dies zu tun, indem Sie Parallel::ForEach mit einer ParallelOptions mit einer MaxDegreeOfParallelism von 10 wie folgt:

Parallel.ForEach(myListOfUrls,
    new ParallelOptions
    {
        MaxDegreeOfParallelism = 10
    },
    url =>
    {
        // processing here
    });

0voto

TomTom Punkte 1

Verwenden Sie Ihren eigenen Scheduler für die TaskFactory.

http://www.codeguru.com/csharp/article.php/c18931/

Dann weisen Sie grundsätzlich 10 Threads über diesen Scheduler zu.

0voto

Ade Miller Punkte 13246

Dies ist wirklich dynamische Aufgabenparallelität. Ihr Code durchläuft die URLs, die Sie haben, und führt den Body für jede URL aus. Es fügt auch alle neuen URLs in die Warteschlange mit einer addMethod und eine gleichzeitige Warteschlange.

public static void ParallelWhileNotEmpty<T>(
  IEnumerable<T> initialValues, 
  Action<T, Action<T>> body)
{
  var opts = new ParallelOptions { MaxDegreeOfParallelism = 10 };
  var from = new ConcurrentQueue<T>(initialValues);  
  while (!from.IsEmpty)
  { 
    var to = new ConcurrentQueue<T>();
    Action<T> addMethod = to.Enqueue; 
    Parallel.ForEach(from, opts. body(v, addMethod));        
    from = to;
  }
}

Auf diese Weise ist die "Schleife" unbegrenzt und wird fortgesetzt, bis Sie keine Arbeit mehr haben. Natürlich würde Ihre echte Anwendung doppelte URLs berücksichtigen und sie nicht hinzufügen usw. Aber dies ermöglicht Ihrer Anwendung, dynamisch Arbeit hinzuzufügen. Sie können die ParallelOptions verwenden, um die Gleichzeitigkeit zu begrenzen, oder Sie können einen Scheduler schreiben.

Weitere Informationen zur dynamischen Aufgabenparallelität finden Sie unter

http://msdn.microsoft.com/en-us/library/ff963551.aspx

Den vollständigen Code für das Beispiel finden Sie unter

http://parallelpatterns.codeplex.com/SourceControl/changeset/view/54510#795590

In den beiden oben genannten Beiträgen werden weitere alternative Varianten dieses Themas erörtert.

Wenn Sie einen benutzerdefinierten Planer wünschen, um den Grad der Parallelität zu begrenzen, sehen Sie sich das Beispiel auf MSDN an

http://msdn.microsoft.com/en-us/library/ee789351.aspx

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X