2010-12-07 13 views
5

Ich habe eine Funktion, die eine Liste von 6100 Listenelementen verarbeitet. Der Code, der verwendet wurde, wenn die Liste nur aus 300 Elementen bestand. Aber stürzt sofort mit 6100 ab. Gibt es eine Möglichkeit, durch diese 6100 Elemente zu schleudern, sagen wir 30 gleichzeitig und führe einen neuen Thread pro Element aus?C# .net Für() Schritt?

for (var i = 0; i < ListProxies.Items.Count; i++) 
    { 
     var s = ListProxies.Items[i] as string; 
     var thread = new ParameterizedThreadStart(ProxyTest.IsAlive); 
     var doIt = new Thread(thread) { Name = "CheckProxy# " + i }; 
     doIt.Start(s); 
    } 

Jede Hilfe würde sehr geschätzt werden.

+3

Für die Aufzeichnung, das Aufspüren und Benennen, was genau abstürzt (die Linie) und die Unfallmeldung helfen sehr, Lösungen zu finden – Eric

Antwort

10

Haben Sie wirklich müssen einen neuen Thread für jedes Arbeitselement spawnen? Es sei denn, es besteht ein echter Bedarf (wenn ja, bitte sagen Sie uns, warum), würde ich Ihnen dringend empfehlen, stattdessen die Managed Thread Pool zu verwenden. Dadurch erhalten Sie die Vorteile des gemeinsamen Zugriffs, die Sie benötigen, aber ohne die Ressourcenanforderungen (sowie die Erstellung, Vernichtung und den Austausch von Kontextkosten) von Tausenden von Threads. Wenn Sie .NET 4.0 verwenden, sollten Sie auch die Verwendung von Task Parallel Library in Betracht ziehen.

Zum Beispiel:

for (var i = 0; i < ListProxies.Items.Count; i++) 
{ 
    var s = ListProxies.Items[i] as string; 
    ThreadPool.QueueUserWorkItem(ProxyTest.IsAlive, s);  
} 

Auf einer anderen Anmerkung, ich würde ernsthaft die IsAlive Methode betrachtet Umbenennen (die wie eine boolean Eigenschaft oder Methode aussieht) seit:

  1. Es hat eindeutig eine void IsAlive(object) Unterschrift .
  2. Es hat beobachtbare Nebenwirkungen (von Ihrem Kommentar, dass es "einen Fortschrittsbalken erhöhen und einen 'funktionierenden' Proxy zu einer neuen Liste hinzufügen").
+1

Der ThreadPool würde absolut der Weg sein, hier zu gehen. Threads sind teuer. – lesscode

+0

Einverstanden. Wenn es sich nicht um lange laufende Threads handelt, wäre dies ein Platz für den Thread-Pool. Ich denke du könntest auch die parallele Bibliothek anschauen und parallel.for verwenden, um die Last über Kerne zu verteilen. – Zippit

+0

@Wayne Threads sind nicht wirklich teuer ... 6000 Threads ist nur rein exzessiv, obwohl :-) (Sie haben Recht, etwas zu verwenden, um die Nummer vernünftig zu verwalten.) –

3

Die Anzahl der Threads, die Sie spawnen können, ist begrenzt. 6100 Threads scheinen ziemlich exzessiv zu sein.

Ich stimme zu Gewinnen Ani, sollten Sie in einen ThreadPool oder sogar einen Producer/Consumer-Prozess je nachdem, was Sie versuchen zu erreichen.

Es gibt eine ganze Reihe von Prozessen für den Umgang mit Multithread-Anwendungen, aber ohne zu wissen, was Sie am Anfang tun, gibt es wirklich keinen anderen Ansatz als ThreadPool oder Producer/Consumer (Queues with SyncEvents).

Auf jeden Fall sollten Sie wirklich versuchen, die Anzahl der Threads auf ein Minimum zu beschränken, sonst laufen Sie das Risiko von Thread-Sperren, Spin-Locks, Warte-Locks, Dead-Locks, Race Conditions, Wer weiß was, etc ...

Wenn Sie gute Informationen über Threading mit C# möchten, lesen Sie das Buch Concurrent Programming on Windows By Joe Duffy, es ist wirklich hilfreich.

Verwandte Themen