Abhängige Tasks in der C # -Warteschlange, die von einem Threadpool verarbeitet werden sollen

Ich möchte abhängige Aufgaben über mehrere Flows in die Warteschlange stellen, die der Reihe nach (in jedem Flow) verarbeitet werden müssen. Die Flows können parallel verarbeitet werden.

Angenommen, ich benötige zwei Warteschlangen und möchte, dass die Aufgaben in jeder Warteschlange in der richtigen Reihenfolge verarbeitet werden. Hier ist ein Beispiel-Pseudocode, um das gewünschte Verhalten zu veranschaulichen:

Queue1_WorkItem wi1a=...;

enqueue wi1a;

... time passes ...

Queue1_WorkItem wi1b=...;

enqueue wi1b; // This must be processed after processing of item wi1a is complete

... time passes ...

Queue2_WorkItem wi2a=...;

enqueue wi2a; // This can be processed concurrently with the wi1a/wi1b

... time passes ...

Queue1_WorkItem wi1c=...;

enqueue wi1c; // This must be processed after processing of item wi1b is complete

Hier ist ein Diagramm mit Pfeilen, die Abhängigkeiten zwischen Arbeitselementen veranschaulichen:

Die Frage ist, wie mache ich das mit C # 4.0 / .NET 4.0? Im Moment habe ich zwei Worker-Threads, einen pro Warteschlange und ich benutze einenBlockingCollection<> für jede Warteschlange. Ich möchte stattdessen den .NET-Thread-Pool nutzen und Worker-Threads Elemente gleichzeitig (über Flows hinweg) verarbeiten lassen, jedoch seriell innerhalb eines Flows. Mit anderen Worten, ich möchte angeben können, dass wi1b zum Beispiel von der Fertigstellung von wi1a abhängt, ohne die Fertigstellung verfolgen und sich an wi1a erinnern zu müssen, wenn wi1b eintrifft. Mit anderen Worten, ich möchte nur sagen: "Ich möchte ein Arbeitselement für Warteschlange 1 senden, das seriell mit anderen Elementen verarbeitet werden soll, die ich bereits für Warteschlange 1 gesendet habe, möglicherweise jedoch parallel zu Arbeitselementen, die an andere Warteschlangen gesendet wurden."

Ich hoffe, diese Beschreibung hat Sinn ergeben. Wenn nicht, können Sie gerne Fragen in den Kommentaren stellen, und ich werde diese Frage entsprechend aktualisieren.

Danke fürs Lesen.

Aktualisieren:

Um "fehlerhafte" Lösungen zusammenzufassen, hier sind die Lösungen aus dem Abschnitt "Antworten", die ich nicht verwenden kann, und die Gründe, warum ich sie nicht verwenden kann:

Für TPL-Aufgaben muss die vorherige Aufgabe für a angegeben werdenContinueWith(). Ich möchte nicht wissen, welche Aufgabe in der Warteschlange ausgeführt wurde, wenn eine neue Aufgabe gesendet wird.

TDF ActionBlocks sahen vielversprechend aus, aber anscheinend werden auf einem ActionBlock veröffentlichte Elemente parallel verarbeitet. Ich muss die Elemente für eine bestimmte Warteschlange seriell verarbeiten.

Update 2:

RE: ActionBlocks

Es scheint, dass die EinstellungMaxDegreeOfParallelism Die Option "Eins" verhindert die parallele Verarbeitung von Arbeitselementen, die an ein einzelnes gesendet wurdenActionBlock. Daher scheint es, dass mit einemActionBlock Per Queue löst mein Problem mit dem einzigen Nachteil, dass dies die Installation und Bereitstellung der TDF-Bibliothek von Microsoft erfordert und ich auf eine reine .NET 4.0-Lösung gehofft habe. Bisher ist dies die vom Kandidaten akzeptierte Antwort, es sei denn, jemand kann eine Möglichkeit finden, dies mit einer reinen .NET 4.0-Lösung zu tun, die nicht zu einem Arbeitsthread pro Warteschlange (den ich bereits verwende) verkommt.

Antworten auf die Frage(4)

Ihre Antwort auf die Frage