2016-08-26 17 views
5

czytałem Dataflow (Task Parallel Library), i nie jest częścią, która mówi:Zrozumienie TPL Dataflow stopień równoległości zamawiania

Po określeniu maksymalnego stopnia równoległości, który jest większy niż 1, wiele wiadomości są przetwarzane jednocześnie i dlatego wiadomości mogą nie być przetwarzane w kolejności, w jakiej zostały odebrane. Kolejność, w jakiej komunikaty są wyprowadzane z bloku, zostanie jednak poprawnie uporządkowana.

Co to znaczy?

przykład, mogę ustawić blok działań ze stopnia równoległości = 5:

testActionBlock = new ActionBlock<int>(i => Consumer(i), 
      new ExecutionDataflowBlockOptions() 
      { 
       MaxDegreeOfParallelism = 5 
      }); 

await Producer(); 
testActionBlock.Completion.Wait(); 

mój producent() Numery zasadzie kolejki do bloku:

private async Task Producer() 
{ 
    for (int i=0; i<= 1000; i++) 
    { 
     await testActionBlock.SendAsync(i); 
    } 
    testActionBlock.Complete(); 
} 

A moja Konsumentów (I) po prostu wypisz linie:

private async Task Consumer(int i) 
{ 
    if (i == 1) 
    { 
     await Task.Delay(5000); 
    } 
    Console.WriteLine(i); 
} 

Czy to oznacza, że ​​Konsument (2) zostanie zablokowany do czasu Konsumenta (1) ha s skończone przetwarzanie (skoro istnieje opóźnienie 5 sekund)? Przetestowałem kod i wydaje się, że tak nie jest. Nawet gdy usunąłem 5-sekundowe opóźnienie, nie widzę, żeby dane wyjściowe były poprawne.

[Aktualizacja]

bBlock = new BufferBlock<int>(option); 

testActionBlock = new ActionBlock<int>(i => Consumer(i), 
    new ExecutionDataflowBlockOptions() 
    { 
     MaxDegreeOfParallelism = 5 
    }); 

bBlock.LinkTo(testActionBlock); 

await Producer(); 
testActionBlock.Completion.Wait(); 

mój producent() teraz doda do bBlock:

private async Task Producer() 
{ 
    for (int i=0; i<= 1000; i++) 
    { 
     await bBlock.SendAsync(i); 
    } 
    bBlock.Complete(); 
} 

Tak więc, w tym przypadku Konsumentów (1) będzie czekać przez 5 sekund, zanim Konsument (2) może kontynuować?

Odpowiedz

3

nr DoP można myśleć jako wątków (nie dokładnie, ale łatwy sposób myśleć o nim)

Więc na 5, będzie starał się przetworzyć 5 naraz. Ponieważ # 1 trwa 5 sekund, # 2 na pewno zakończy się jako pierwszy. Prawdopodobnie tak będzie # 3, # 4 i # 5. Prawdopodobnie nawet # 6 (ponieważ # 2 jest zrobione, DoP zezwoli na rozpoczęcie od # 6)

Nawet bez opóźnienia, nie ma gwarantowanego zamówienia do przetwarzania. Więc nigdy nie polegaj na zamówieniu , KTÓRA WYKONUJE. Powiedziawszy to, podczas korzystania z komunikatów wyjściowych (NOT prtinting, ponieważ jest to kolejność ich wykonania), zostaną one ponownie posortowane w kolejności, w jakiej zostały wprowadzone, nawet jeśli zostały wykonane w dowolnej kolejności.

+0

dzięki za wyjaśnienia. Ale wciąż nie jestem pewien, kiedy "komunikaty wyjściowe ... zostaną ponownie posortowane". Zaktualizowałem moje oryginalne pytanie, aby sprawdzić, czy moje rozumienie jest poprawne? – SimonSays

+0

Przepływ danych TPL zapewnia pełny mechanizm przesyłania komunikatów, zaprojektowany do uzyskiwania danych z bloków. Sprawdź ten świetny przewodnik od MS z dokładnymi przykładami. https://msdn.microsoft.com/en-us/library/hh228597(v=vs.110).aspx – Tim