2011-01-05 13 views
18

Ich verstehe, dass die neue TPL (Task Parallel Library) die Parallel.ForEach() implementiert hat, so dass es mit "ausdrückliche Parallelität" funktioniert. Das heißt, es wird nicht garantiert, dass Ihre Delegierten in mehreren Threads ausgeführt werden, sondern es wird geprüft, ob die Hostplattform mehrere Kerne hat. Wenn dies der Fall ist, verteilt es die Arbeit auf die Kerne (im Wesentlichen 1 Thread pro Kern). ..NET 4 ... Parallel.ForEach() Frage

Wenn das Host-System nicht mehrere Kerne hat (es wird immer schwieriger, einen solchen Computer zu finden), wird der Code sequenziell wie eine "normale" foreach-Schleife ausgeführt. Ziemlich cooles Zeug, ehrlich gesagt.

Normalerweise würde ich etwas tun, wie folgt aus meinem langen laufenden Betrieb auf einem Hintergrund-Thread aus dem Threadpool zu platzieren:

ThreadPool.QueueUserWorkItem (neu WaitCallback (Targetmethod), neu Object2PassIn());

In einer Situation, in der der Host-Computer nur einen einzigen Kern hat, platziert die Parallel.ForEach() der TPL den Aufruf automatisch auf einen Hintergrund-Thread? Oder sollte ich manuell irgendwelche TPL-Aufrufe von einem Hintergrund-Thead aufrufen, so dass, wenn ich von einem einzelnen Kern-Computer zumindest diese Logik aus dem Dispatch-Thread der GUI ausführe?

Meine Sorge ist, wenn ich die TPL verantwortlich für all dies verlassen möchte ich sicherstellen, wenn es bestimmt, es ist eine einzige Kern-Box, die es immer noch den Code, der innerhalb der Parallel.ForEach() -Schleife auf einen Hintergrund-Thread ist wie ich es getan hätte, um meine GUI nicht zu blockieren.

Dank für irgendwelche Gedanken oder Ratschläge, die Sie haben ...

+1

Nur eine kurze Nachfassaktion: TPL Rocks! Ich komme nicht darüber hinweg, wie viel schneller ich in der Lage bin, verschiedene Anwendungen mit nur ein paar kleinen Anpassungen mit TPL-Anrufen im Vergleich zum "Standard" -Tarif zu machen. Ich beobachte Bearbeitungszeiten bei verschiedenen Artikeln, die um mehr als 80% reduziert wurden. MS hat es wirklich aus dem Park geschafft - tolle Arbeit Jungs. – BonanzaDriver

Antwort

19

sind Ihre Annahmen nicht korrekt.
Parallel.For ist immer ein blockierender Anruf.

Auch wenn der Computer über mehrere Kerne verfügt, wartet er immer noch auf die Beendigung aller Threads, bevor er zurückkehrt.

Wenn Sie die Benutzeroberfläche nicht einfrieren möchten, müssen Sie den ThreadPool immer explizit aufrufen.

+0

Cool - danke SLaks – BonanzaDriver

+3

Könnte immer in eine Aufgabe stecken, und eine Fortsetzung verwenden, um auf die Fertigstellung zu warten, und dann die Benutzeroberfläche benachrichtigen. –

0

Ich denke, wenn Sie genaue Anforderungen über Instanz/Thread-Anzahl haben, müssen Sie es selbst tun. Ich habe den Eindruck, dass die Parallel.ForEach-Art von Aufrufen dazu dient, deklarativ Kerne einzubeziehen. Ich weiß es nicht genau, aber ich habe den hinterhältigen Verdacht, dass es eine schlechte Wahl für etwas wäre, das I/O blockiert (als Beispiel).

+0

Aus der Dokumentation, die ich bisher gelesen habe, wurde ursprünglich für "prozessorgebundene" Problemsätze gedacht. Dies soll jedoch nicht ausgeschlossen werden, dass es für IO verwendet wird. Was mich dazu brachte, die TPL ernsthaft zu betrachten, ist die Tatsache, dass ich eine App habe, die ungefähr 7.800 Webabfragen durchführt ... Ich habe eine Dual-Quad-Core-Prozessorbox (3,0 GHz Xeons) mit 24 GB RAM auf Windows 7 Ultimate 64-Bit-Edition ... und diese dauern ~ 25 bis 28 Minuten. Es gibt eine zusätzliche Verarbeitung des HTML-Downloads, aber Sie bekommen meinen Punkt. Ich änderte dies in einen TPL-Anruf und es dauerte <5 Minuten. – BonanzaDriver

0

Gute Frage. Ich würde annehmen, dass es immer noch einen Thread spawnen wird, selbst wenn es nur einen einzigen Kern gibt.

Ich müsste einen Test auf einer Single-Core-Maschine ausführen. Da ich keine habe, werde ich die virtuelle Maschine benutzen und die CPU der it-Umgebung auf 1 setzen und sehen, wie viele Threads das Parallel ForEach erzeugen wird.

Möglicherweise möchten Sie folgendes lesen:

Does Parallel limit the Number of Active Threads

1

Durch meine Erfahrung mit Parallel.ForEach und Parallel.For Schleifen, ich habe bemerkt, dass die Reihenfolge, in der falschen Reihenfolge sein kann, etwas, das Sie möchten zu überlegen, bevor Sie implementieren.

wie zum Beispiel eine grundlegende for-Schleife erzeugt:

Produkt 1 Produkt 2 Produkt 3 Produkt 4

und die parallele Schleife erzeugen kann, aber nicht immer:

Produkt 3 Produkt 1 Produkt 2 Produkt 4

Denken Sie nur daran, Jungs.