Benutzer mit den meisten Antworten
Maximal Anzahl von Threads in einer Application

Frage
-
Hallo NG,
ich habe schon nach dem Problem bei Google angesehen aber leider nichts gefunden.
In meinem Programm erfasst bzw. lädt der Anwender Datensätze ein. Für jeden Datensatz muss ich Übertragungen über eine SOAP-Schnittstelle erzeugt. Ich starte nun für jeden Datensatz einen eigenen Thread der mit dem Server kommuniziert und stirbt. Je nach Daten kann das 30 Sekunden oder auch ein paar Minuten dauern.
Nun frage ich mich gibt es bei Begrenzung der max. zu gleich Zeit arbeitenden Threads?
Danke für jeden Hinweis und Tipp.
Grüße Ingo
- Bearbeitet Marcel RomaModerator Mittwoch, 28. August 2013 08:37 Titel korrigiert
Antworten
-
Hallo Ingo,
Threading hilft nur bei CPU-bezogenen Problemen, d.h. während der eine Thread von einem bestimmten Prozessorkern abgearbeitet wird, kann parallel dazu ein anderer Thread in einem weiteren Kern abgearbeitet werden. Das steigert die Effizienz solange die Anzahl der gleichzeitig ausgeführten Threads in einem gesunden Verhältnis zur Anzahl der Prozessorkerne ist (Pi mal Daumen: 2 x Anzahl der Kerne) und die Threads in der zugeteilten Zeitspanne was tun und nicht warten.
Das Downloaden der Daten ist aber keine CPU-bezogene Operation, sondern eine E/A-Operation. Diese Art von Operationen zeichnen sich dadurch aus, dass sie die meiste Zeit über auf das Abschließen der E/A warten.
Egal wie Du diese Arbeit auf die Prozessorkerne verteilst, wird dies das Herunterladen der Daten nicht beschleunigen. Im Gegenteil: Wenn Du zuviele Threads erzeugst, unterbricht der Windows Scheduler die einzelnen Threads häufiger und das kostet Zeit und Performanz. Auf der anderen Seite bombardierst Du den Server ununterbrochen mit Anfragen, was die Sache auch nicht einfacher macht.
Wenn Du - aus mir unbekannten, hier nicht angeführten Gründen - Threading benutzen mußt, dann verwende doch den Threadpool. Optimal funktioniert das, wenn das Herunterladen der Daten < 250 ms ist.
Bei E/A-Operationen sollte man asynchron arbeiten (nicht zu verwechseln mit Threading). In C# 5.0 gibt es dazu async/await. Wenn Du etwas wie WebClient.DownloadStringAsync() verwendest, dann kannst Du über ThreadPool.QueueUserWorkItem(DoDownload) arbeiten. Das ist zwar weniger optimal als async/await, funktioniert aber recht gut, weil die Verwaltung des ThreadPools von der CLR übernommen wird. Über die Methode ThreadPool.SetMaxThreads() kannst Du beeinflussen wieviel Threads maximal gleichzeitig aktiv sein dürfen. Die restlichen Threads kommen in eine Warteschlange, Du mußt schon aufpassen, dass die nicht zu groß wird, denn sonst nimmt die CLR an, dass die CPU zu beschäftigt ist und die Scheduling-Performanz der Threads im Pool wird suboptimal.
Gruß
Marcel- Als Antwort markiert IngoManthey Mittwoch, 28. August 2013 11:16
Alle Antworten
-
Hi Ingo.
Vielleicht hilft dir dieser Google-Fund weiter:
http://stackoverflow.com/questions/145312/maximum-number-of-threads-in-a-net-app
LG, Dennis.
EDI Consultant/Developer
Ich nutze meistens VB6 und VS2005 bis VS2012
Bitte die Antworten sowie weitere hilfreiche Beiträge von Mitgliedern markieren. Vielen Dank.
-
Hallo Ingo,
Threading hilft nur bei CPU-bezogenen Problemen, d.h. während der eine Thread von einem bestimmten Prozessorkern abgearbeitet wird, kann parallel dazu ein anderer Thread in einem weiteren Kern abgearbeitet werden. Das steigert die Effizienz solange die Anzahl der gleichzeitig ausgeführten Threads in einem gesunden Verhältnis zur Anzahl der Prozessorkerne ist (Pi mal Daumen: 2 x Anzahl der Kerne) und die Threads in der zugeteilten Zeitspanne was tun und nicht warten.
Das Downloaden der Daten ist aber keine CPU-bezogene Operation, sondern eine E/A-Operation. Diese Art von Operationen zeichnen sich dadurch aus, dass sie die meiste Zeit über auf das Abschließen der E/A warten.
Egal wie Du diese Arbeit auf die Prozessorkerne verteilst, wird dies das Herunterladen der Daten nicht beschleunigen. Im Gegenteil: Wenn Du zuviele Threads erzeugst, unterbricht der Windows Scheduler die einzelnen Threads häufiger und das kostet Zeit und Performanz. Auf der anderen Seite bombardierst Du den Server ununterbrochen mit Anfragen, was die Sache auch nicht einfacher macht.
Wenn Du - aus mir unbekannten, hier nicht angeführten Gründen - Threading benutzen mußt, dann verwende doch den Threadpool. Optimal funktioniert das, wenn das Herunterladen der Daten < 250 ms ist.
Bei E/A-Operationen sollte man asynchron arbeiten (nicht zu verwechseln mit Threading). In C# 5.0 gibt es dazu async/await. Wenn Du etwas wie WebClient.DownloadStringAsync() verwendest, dann kannst Du über ThreadPool.QueueUserWorkItem(DoDownload) arbeiten. Das ist zwar weniger optimal als async/await, funktioniert aber recht gut, weil die Verwaltung des ThreadPools von der CLR übernommen wird. Über die Methode ThreadPool.SetMaxThreads() kannst Du beeinflussen wieviel Threads maximal gleichzeitig aktiv sein dürfen. Die restlichen Threads kommen in eine Warteschlange, Du mußt schon aufpassen, dass die nicht zu groß wird, denn sonst nimmt die CLR an, dass die CPU zu beschäftigt ist und die Scheduling-Performanz der Threads im Pool wird suboptimal.
Gruß
Marcel- Als Antwort markiert IngoManthey Mittwoch, 28. August 2013 11:16
-
Wieso müssen es eigentlich mehrere Aufrufe bzw. Verbindungen (und damit Threads) mit dem Server sein, wenn möglicherweise bereits vor dem Start der ersten Verbindung bereits klar ist, welche und wie viele Daten insgesamt heruntergeladen werden sollen? Kann man sich die nicht alle auf einmal herunterladen?
(Die Frage schließt sich an die von Marcel erwähnten "hier nicht aufgeführten Gründe" an)
LG, Dennis.
EDI Consultant/Developer
Ich nutze meistens VB6 und VS2005 bis VS2012
Bitte die Antworten sowie weitere hilfreiche Beiträge von Mitgliedern markieren. Vielen Dank.
-
Hallo Dennis,
zuerst einmal Danke für Deine Antwort. Das geht leider nicht aus folgenden Gründen:
1. Die Daten werden mit unterschiedlichen Server ausgetauscht.
2. Der Datenaustausch wird in unterschiedlichen Formen (Stammdaten) vorgenommen.
3. Ist abhängig von den geänderten Daten. Löschen/Ändern und Neuaufnahme.
Grüße Ingo
-
Hallo Marcel,
zuerst einmal vielen Dank für Deine Antwort.
Ja Du hast Recht. Ich war das ganz schön auf dem Holzweg, mein Problem mit einzelnen Thread zu realisieren. Für mich war immer asynchron = Threads.
Ich werden zwar weiterhin die Arbeiten in einen Thread erledigen, weil es nicht nur um die SOAP Abfragen geht, aber ich werden alle Aufträge in einem Thread abarbeiten.
Danke das war eine große Hilfe.
Grüße Ingo