2010-02-16 17 views
18

ma statyczny element członkowski AsParallel. Jeśli mam IEnumerable<T> i chcę używać Parallel.ForEach oznacza to, że zawsze powinienem używać AsParallel?Czy Parallel.ForEach wymaga AsParallel()

np. Czy oba te elementy są poprawne (wszystko inne jest równe)?

bez AsParallel:

List<string> list = new List<string>(); 
Parallel.ForEach<string>(GetFileList().Where(file => reader.Match(file)), f => list.Add(f)); 

lub AsParallel?

List<string> list = new List<string>(); 
Parallel.ForEach<string>(GetFileList().Where(file => reader.Match(file)).AsParallel(), f => list.Add(f)); 

Odpowiedz

21

To zależy od tego, jak się nazywa, to osobne kwestie.

.AsParallel() Równolegle do numerowania wyliczanie zamiast delegowania zadań.

Równolegle do pętli , przypisując zadania do wątków roboczych dla każdego elementu.

Więc jeśli twoje wyliczenie źródła nie zyskuje na równoległości (np. reader.Match(file) jest kosztowne), są one równe. Na ostatnie pytanie, tak, oba są również prawidłowe.

Ponadto, istnieje jeszcze jedna konstrukcja może warto spojrzeć na to, że skraca się nieco, wciąż się maksymalną korzyść PLINQ:

GetFileList().Where(file => reader.Match(file)).ForAll(f => list.Add(f)); 
+2

Hmmm ... co dokładnie parrallelizing wyliczenie? a przynajmniej jak można ową paralelizację oddzielić od delegacji zadań? – dkackman

+2

@dkackman '.AsParallel()' przygotowuje numerację do wykonania równoległego, w szczególności równoległą wersję '.SelectMany()' w tym przypadku. Pomyśl o wyliczeniu, które ma mocną klauzulę "Gdzie", ale bez porządku, możemy ocenić, gdzie klauzula jednocześnie w tak wielu rdzeniach, jak to możliwe, dając kolejne w wyliczeniu do następnego dostępnego wątku, czyniąc go prawie 'n' razy szybszym. To, co robimy z tym wynikiem, może być później obsługiwane w ten sam sposób, synchronicznie w jednym wątku lub rozprzestrzenione na dostępne rdzenie, czyli część "Parallel.ForEach" lub ".ForAll", ma sens? –

+0

To ma sens. Dzięki Nick. – dkackman

Powiązane problemy