2012-09-11 8 views
7

Mam listę numerów kont. Numer konta Foreach Muszę zadzwonić do metody ProcessAccount. Przetworzy się około 150 000 kont, a przetworzenie każdego konta może potrwać od 0,5 do 2 sekund.Łatwy sposób na przetwarzanie kolejki z N wątków w C#?

Chciałbym ustawić wątki w jakiś sposób, dzięki czemu mogę przetwarzać na przykład 4 konta na raz.

Czy istnieje prosty wzór, którego mogę użyć w tym celu?

Co mogę zrobić, to rozpocząć 4 wątki przetwarzające pierwsze 4 konta, a następnie, po zakończeniu każdego pojedynczego wątku, rozpocznij kolejny wątek z następnym kontem, aż wszystkie konta zostaną przetworzone.

+0

FYI - To najprawdopodobniej zostanie uruchomiony z aplikacji konsoli. – AWeim

+4

Jaka jest zależność od 'ProcessAccount'? Czy jest to operacja związana z obliczeniami, czy operacja związana I/O? –

+1

Bryan ma dobry punkt, wspominasz listę, czy to jest lista ? Jeśli chcesz odczytać dane z dysku lub zadzwonić do usług zdalnych lub coś jest bardzo różne, niż wtedy, gdy masz wszystkie potrzebne dane gotowe do użycia w pamięci. Aby przyspieszyć działanie, najpierw musisz zidentyfikować wąskie gardło. – gjvdkamp

Odpowiedz

12

Jest to łatwe w obsłudze dzięki TPL (Task Parallel Library). Byłoby wyglądać

ParallelOptions options = new ParallelOptions() { MaxDegreeOfParallelism = 4 }; 
Parallel.ForEach(accounts, options, a => 
{ 
    ProcessAccount(a); 
}); 

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

nocie, że OC może zdecydować, aby uruchomić mniej niż 4 współbieżnych wątków, ale nie będzie działać więcej niż 4 na podstawie podanych opcji. Może to zrobić, na przykład, jeśli ustali, że podana lamda (która wywołuje ProcessAccount) jest związana z CPU, a w systemie jest mniej niż 4 rdzenie procesora. Ogólnie rzecz biorąc, szczególnie w .NET 4.5, TPL podejmuje bardzo dobre decyzje dotyczące liczby wątków do użycia.

Jak zauważa @Servy w komentarzach, chyba że masz bardzo konkretny powód, aby ograniczyć kod do 4 wątków, najlepiej po prostu pozwolić TPL uporządkować, ile wątków będzie używać samodzielnie. W ten sposób, jeśli ten sam kod działa na procesorze 128-rdzeniowym w roku 2018, długo po tym, jak przejdziesz do innych rzeczy, możesz korzystać ze wszystkich 128 rdzeni).

+1

Jeśli nie chcesz celowo ograniczać zużytych zasobów, aby udostępnić je innym, zazwyczaj lepiej nie podawać więcej, niż potrzebujesz. Im większa swoboda, jaką dajesz bibliotece do robienia tego, co uważasz za stosowne, tym lepiej się sprawdzi. – Servy

+0

@Servy: To bardzo dobry punkt. Zgadzam się w 100%. –

1

Zastosowanie PLinq:

var accounts = //some 150,000 account numbers 
accounts.AsParallel().ForAll(ProcessAccount); 

lub, jeżeli wymagane są inne argumenty, użycie wyrażenia lambda:

accounts.AsParallel().ForAll(account => ProcessAccount(account, argument2, argument3)); 
+0

Nie ogranicza to maksymalnej liczby wątków do 4. –

+1

@EricJ. nie, masz rację, nie ma. Z mojego doświadczenia wynika, że ​​PLinq wykonuje wystarczająco dużo pracy dławiąc się bez jakiejkolwiek pomocy ode mnie, ale nie jestem na terytorium wrażliwym na wydajność. – phoog

+1

@EricJ. Zgaduję, że OP nie jest zaznajomiony z pojęciem puli wątków (i oczekuje się, że będzie musiał sam wykonać z niezmienną liczbą wątków) i nie wymaga biznesowego ograniczenia go do 4 wątków. – Servy

Powiązane problemy