-1

Ich habe eine IEnumerable mit vielen Elementen, die parallel verarbeitet werden müssen. Die Artikel sind nicht CPU-intensiv. Idealerweise sollten diese Elemente gleichzeitig auf 100 Threads oder mehr ausgeführt werden.C# - Parallel Foreach langsame Erstellung der Threads

Ich habe versucht, dies mit Parallel.ForEach() zu tun. Das funktioniert, aber das Problem ist, dass neue Threads zu langsam spawnen. Es dauert eine (zu) lange Zeit bevor die Parallel.Foreach() die 100 Threads erreicht. Ich weiß, dass es eine MaxDegreeOfParallelism -Eigenschaft gibt, aber das ist ein Maximum, nicht minimal.

Gibt es eine Möglichkeit, die foreach sofort auf 100 Threads auszuführen? ThreadPool.SetMinThreads ist etwas, das wir vermeiden möchten, weil es Auswirkungen auf den gesamten Prozess hat.

Gibt es eine Lösung mit einem benutzerdefinierten Partitionierer?

+1

Well 'Parallel.ForEach' verwendet Pool-Thread und so spielt, aber es ist Regeln, so' SetMinThreads' die einzige Option scheint (wenn Sie speziell verwenden 'Parallel.ForEach' wollen). – Evk

+0

Können Sie eine Probe zur Verfügung stellen, die Ihre _Processing_details zeigt. Ist es IO-gebunden/CPU gebunden, ist es Multi-Step-Prozesse .. etc.? – JSteward

+0

Aber, wenn Ihre Aufgaben nicht CPU-intensiv sind (und so - meist IO intensive) - können Sie async \ await in Kombination mit SemaphoreSlim verwenden, um Nebenläufigkeit zu begrenzen, zum Beispiel wie hier http://stackoverflow.com/a/10810730/5311735 (aber benutze Task.Run (warte nicht ...) wie dort). – Evk

Antwort

-2

Ich habe statt Parallel Erfolg mit Threadpool hat:

public static void ThreadForEach<T>(this IEnumerable<T> items, Action<T> action) 
{ 
    var mres = new List<ManualResetEvent>(); 

    foreach (var item in items) 
    { 
     var mre = new ManualResetEvent(false); 

     ThreadPool.QueueUserWorkItem((i) => 
     { 
      action((T)i); 
      mre.Set(); 
     }, item); 

     mres.Add(mre); 
    } 

    mres.ForEach(mre => mre.WaitOne()); 
} 

In Fällen, in denen ich je hatte, diese zu verwenden, es lief schneller als Versuche mit Parallel.ForEach. Ich kann nur spekulieren, dass es so ist, weil es versucht, bereits existierende Threads zu verwenden (anstatt den Overhead zu verwenden, um neue zu erstellen).

+0

Sie könnten die Diskussion von Threads vollständig und foreach vollständig vermeiden, indem Sie eine einfache PLINQ-Abfrage verwenden. Aber wenn die Verarbeitung des OP in irgendeiner Weise IO gebunden ist, dann muss dies in Richtung einer Synchronisationslösung gehen. – JSteward

+0

Parallel verwendet den Threadpool ebenfalls. Parallel ist nicht kaputt. Wie auch immer, dein Code hat eine Menge Probleme. Erstens verwendet es eine "Liste" anstelle einer gleichzeitigen Sammlung. Zweitens ist es völlig überflüssig. 'warten Task.WaitAll (items.Select (it => Task.Run (action (it)). ToArray())' würde genau das gleiche tun –

+0

Schließlich ist 'Parallel' für * Daten * Parallelität gemeint Sie möchten eine große Menge an Daten verarbeiten, nicht viele Aufgaben.Typischerweise brauchen Sie keine Aufgaben mehr, als es Kerne gibt, um eine Partition der Daten jeweils zu verarbeiten.Wenn die Aktion blockiert, ist es ein Missbrauch von 'Parallel' –

0

Ich pinge viele Geräte mit einer Zeitüberschreitung von 5 Sekunden an. Wie würdest du das so schnell wie möglich mit nur 4 Threads (4cores) machen?

Ich gehe davon aus, Ihre Ping-Geräte in einem LAN und jeder ist identifizierbar und erreichbar durch eine IP-Adresse.

namespace PingManyDevices { 

    public class DeviceChecker {     

     public async Task<PingReply[]> CheckAllDevices(IEnumerable<IPAddress> devices) { 
      var pings = devices.Select(address => new Ping().SendPingAsync(address, 5000)); 
      return await Task.WhenAll(pings); 
     } 
     /*** 
     * Maybe push it a little further 
     ***/ 
     public async Task<PingReply[]> CheckAllDevices(IEnumerable<IPAddress> devices) { 
      var pings = devices.AsParallel().Select(address => new Ping().SendPingAsync(address, 5000)); 
      return await Task.WhenAll(pings); 
     }   
    } 
} 
Verwandte Themen