Zadania zależne od kolejkowania C #, które mają być przetwarzane przez pulę wątków

Chcę kolejkować zadania zależne w kilku przepływach, które muszą być przetwarzane w kolejności (w każdym przepływie). Przepływy mogą być przetwarzane równolegle.

Mówiąc konkretnie, powiedzmy, że potrzebuję dwóch kolejek i chcę, aby zadania w każdej kolejce były przetwarzane w kolejności. Oto przykładowy pseudokod ilustrujący pożądane zachowanie:

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

Oto diagram ze strzałkami ilustrującymi zależności między elementami pracy:

Pytanie brzmi, jak to zrobić za pomocą C # 4.0 / .NET 4.0? W tej chwili mam dwa wątki robocze, po jednym na kolejkę i używamBlockingCollection<> dla każdej kolejki. Zamiast tego chciałbym wykorzystać pulę wątków .NET i jednocześnie posiadać elementy procesu wątków roboczych (między przepływami), ale szeregowo w obrębie przepływu. Innymi słowy, chciałbym móc wskazać, że na przykład wi1b zależy od ukończenia wi1a, bez konieczności śledzenia zakończenia i zapamiętania wi1a, gdy nadejdzie wi1b. Innymi słowy, chcę tylko powiedzieć: „Chcę przesłać element pracy do kolejki1, który ma być przetwarzany seryjnie z innymi elementami, które już przesłałem do kolejki1, ale prawdopodobnie równolegle z elementami pracy przesyłanymi do innych kolejek”.

Mam nadzieję, że ten opis miał sens. Jeśli nie, proszę zadawać pytania w komentarzach, a ja odpowiednio zaktualizuję to pytanie.

Dziękuje za przeczytanie.

Aktualizacja:

Podsumowując do tej pory „wadliwe” rozwiązania, oto rozwiązania z sekcji odpowiedzi, których nie mogę użyć i powód (-y), dlaczego nie mogę ich użyć:

Zadania TPL wymagają określenia poprzedniego zadania dlaContinueWith(). Nie chcę utrzymywać wiedzy o poprzedzającym zadaniu kolejki przy składaniu nowego zadania.

TDF ActionBlocks wyglądały obiecująco, ale wydaje się, że elementy wysłane do ActionBlock są przetwarzane równolegle. Potrzebuję, aby elementy dla konkretnej kolejki były przetwarzane seryjnie.

Aktualizacja 2:

RE: ActionBlocks

Wydaje się, że ustawienieMaxDegreeOfParallelism opcja do jednego zapobiega równoległemu przetwarzaniu elementów pracy przesłanych do pojedynczegoActionBlock. Dlatego wydaje się, że posiadanieActionBlock na kolejkę rozwiązuje mój problem, jedyną wadą jest to, że wymaga to instalacji i wdrożenia biblioteki TDF od Microsoft i liczyłem na czyste rozwiązanie .NET 4.0. Jak dotąd jest to odpowiedź zaakceptowana przez kandydata, chyba że ktoś może wymyślić sposób, aby to zrobić za pomocą czystego rozwiązania .NET 4.0, które nie ulega degeneracji do wątku roboczego na kolejkę (którego już używam).

questionAnswers(4)

yourAnswerToTheQuestion