2013-01-08 9 views
5

In diesem Beispiel ist dies die korrekte Verwendung der Parallel.For Schleife, wenn ich die Anzahl der Threads, die die Funktion DoWork auf zehn gleichzeitig ausführen können, begrenzen möchte? Werden andere Threads blockiert, bis einer der zehn Threads verfügbar wird? Wenn nicht, was ist eine bessere multi-threaded Lösung, die mich diese Funktion noch 6000+ mal ausführen lassen würde?Korrekte Verwendung von Parallel für Schleife in C#?

class Program 
{ 
    static void Main(string[] args) 
    { 
     ThreadExample ex = new ThreadExample(); 
    } 
} 

public class ThreadExample 
{ 
    int limit = 6411; 

    public ThreadExample() 
    { 
     Console.WriteLine("Starting threads..."); 
     int temp = 0; 
     Parallel.For(temp, limit, new ParallelOptions { MaxDegreeOfParallelism = 10 }, i => 
     { 
      DoWork(temp); 
      temp++; 
     }); 
    } 

    public void DoWork(int info) 
    { 
     //Thread.Sleep(50); //doing some work here. 

     int num = info * 5; 

     Console.WriteLine("Thread: {0}  Result: {1}", info.ToString(), num.ToString()); 
    } 
} 
+2

'temp ++' ist nicht Thread-sicher. – SLaks

+0

@SLaks Ja, es ist nicht Thread sicher, aber hat es Bedeutung in diesem Wettbewerb? Wie funktioniert Parallel.Für? –

+1

@HamletHakobyan Was meinst du? Die Absicht des Programmierers ist klar; Er möchte die Anzahl der erledigten Aufgaben zählen. Was tatsächlich passiert, ist aufgrund der Rennbedingungen, die möglicherweise dazu führen, dass der Zähler nicht richtig inkrementiert wird, nicht dasselbe. Die Verwendung von "interlocked.Exchange" würde das lösen. Wie bei 'Parallel.For' handelt es sich um eine For-Schleife, bei der die Iterationen (zu einem bestimmten Grad) von mehreren Threads parallel ausgeführt werden. – Servy

Antwort

15

Sie müssen die i auf die Lambda-Funktion als Index übergeben können. Parallel.For entlastet Sie von der Arbeit mit dem Schleifenzähler, aber Sie müssen es verwenden!

Parallel.For(0, limit, new ParallelOptions { MaxDegreeOfParallelism = 10 }, i => 
    { 
     DoWork(i); 
    }); 

Was Ihre anderen Fragen:

  • Ja, das wird richtig die Menge an Fäden begrenzen gleichzeitig arbeiten.
  • Es sind keine Threads blockiert. Die Iterationen werden in die Warteschlange gestellt, und sobald ein Thread verfügbar ist, nimmt er die nächste Iteration (in einer synchronisierten Weise) von der zu verarbeitenden Warteschlange.
+0

MaxDegreeOfParallelism ist was Sie suchen –

+1

@MicahArmantrout Er war das bereits im OP verwenden; das war es nicht, was ihm Schwierigkeiten bereitete. Diese Antwort identifiziert das Problem mit dem OP-Code korrekt. – Servy

+0

Dies ist ein Problem mit der OP-Lösung, aber es beantwortet keine der speziellen Fragen (mit Ausnahme von "Ist das in Ordnung?"). – usr