c# beginner versteht ThreadPool nicht....

Morpheus2200

Semiprofi
Thread Starter
Mitglied seit
04.08.2001
Beiträge
30.945
Moinsen Community,

ich bin ziemlich frisch in c# / Visual Studio.

Bisher kam ich mir viel Google, stackoverflow und Msdn doku ganz gut zurande, aber bei ThreadPools komm ich gerade nicht zurecht.


Ich hab mal eine kurze Demo gebaut, wie ich aktuell die Anzahl gespawnter Threads unter Kontrolle halte:

hastebin

Das ganze ist allerdings recht unelegant, da so immer erst auf Beendigung des aktuellen 'Pakets' gewartet wird.

ThreadPools wäre die elegantere Lösung, allerdings raff ich nicht so ganz, wie ich die zu Verwenden habe, das war meine Idee:

hastebin

findet VS aber gar nicht gut, meint es könnte nicht von 'method group' nach 'WaitCallback' konvertieren. Nun ist die Beschreibung für ThreadPool.QueueUserWorkItem "Queues a method for execution. The method executes when a thread pool thread becomes available."

Ich seh also das Problem nicht so recht. Muss ich die Methode noch verpacken? braucht die irgendeine spezielle Funktion? Ich raffs nicht so ganz.

Wäre mega, wenn mir da jemand etwas Klarheit verschaffen könnte.


UPDATE:

okay, so funktioniert es halbwegs:

hastebin

Ich hab aber das Gefühl da mindestens eine Ecke zu viel zu gehen. Zudem wird wohl das ThreadPool SetMaxThreads nicht verwendet. Meine Entwicklungsumgebung ist eine windows VM mit 2 Kernen. MaxThreads sollte also auf 1 festgelegt werden. Dafür werden die Threads aber zu fix abgearbeitet und die CPU-Last hängt bei 100% statt bei ~60% (10% background-last + 50% threads)


Grüße
 
Zuletzt bearbeitet:
Wenn Du diese Anzeige nicht sehen willst, registriere Dich und/oder logge Dich ein.
Ich weiß nicht wirklich was du erreichen willst, aber der ThreadPool ist nicht für die Kontrolle der Anzahl laufender Threads gedacht, der TP ist eine Art Cache für Threads, damit der Overhead für die Threaderzeugung nicht auftritt wenn du nur kurze Operationen ausführen willst.
Wenn ich dich richtig verstehe, willst du zwar parallelisieren, aber die Parallelität selber kontrollieren, um sie ggf. unter die Anzahl der Kerne zu drücken. Im allgemeinen gibt es dafür von den Bibliotheken her genug Möglichkeiten, das selber zu machen ist praktisch immer falsch, inkl. deinem Ansatz.

Wenn du einfach nur x Operationen Parallel ausführen willst, ist ggf. Parallel.For/Foreach die richtige Wahl, dem kannst du auch in den ParallelOptions die maximale Parallelität übergeben.
Alternativen sind:
Tasks mit async/await, wenn du es selber machen willst und async/await fähig bist
TPL Dataflow (basiert auf Tasks, ist für komplexe Datenflusssysteme gedacht
BeginAsync/EndAsync (IAsyncResult) wenn du z.b. auf IO Resourcen zugreifst und nicht mit Tasks arbeiten kannst


Wenn du das aus Lerngründen wirklich selber machen willst, empfehle ich erstmal die Fähigkeiten der .NET Bibliotheken kennenzulernen, dazu gehört u.A. keine Queue selber zu bauen, sondern den Typ Queue<T>/ConcurrentQueue<T>. Dann gehts weiter mit Synchronisationskonstrukten, z.B. Semaphoren um die Parallelität zu steuern. Dann wende das ggf. zusammen mit Threadpool an. Wenn du jedoch ein Workerkonzept haben willst, das sich nur dann lohnt, wenn der Setup eines Workers extrem lange dauert (vgl. mit der Laufdauer), damit es sich lohnt die Worker "idlen" zu lassen, dann solltest du dir ggf. die normale Thread API anschauen. Ach ja, all diese Grundlagen sind praktisch in jeder moderneren Programmiersprache gleich, d.h. du kannst auch nicht .NET Literatur verwenden um das zu verstehen.
 
Zuletzt bearbeitet:
Moin Tornhoof,

danke für deine Antwort. Du sagst ThreadPool ist nicht zur Kontrolle der Anzahl laufender Threads gedacht, aber wofür ist dann die SetMaxThreads - Methode?

Inzwischen hab ich das ganze Lösen können, wenn auch nicht allzu elegant, tut aber was es soll.

Code:
List<> queue;
List<Thread> runningthreads;

while (elements in queue) {
    if (runningthreads < cores-1) spawn worker & add thread to runningthreads
    else sleep(100) & check foreach thread in runningthreads if alive. if not, remove from list
}

Die ganze Kiste ist nötig, da es sonst windows recht unbedienbar macht, wenn da 500 Arbeiterthreads gleichzeitig loswerkeln, Priorität setzten half auch nicht so richtig.

Ist schon ne weile her, dass ich mit c und java zu tun hatte. Im letzter Zeit eigentlich nur js,php,html,css ... da musste ich mir wenig kopf um Threading machen :p

Mal schauen, ob ich c# weiterverfolge, eigentlich hab ich bis auf Nutzerprobleme lösen mit Windows nix am Hut :P
 
Ich zitiere mal die Hilfe:
"Sie können nicht die maximale Anzahl von Arbeitsthreads oder e/a-Abschlussthreads auf eine Zahl kleiner als die Anzahl der Prozessoren auf dem Computer festgelegt"

Wofür die Funktion gut ist, ist eine andere Frage, die ich nicht beantworten kann. Nie gebraucht bisher.
 
Zuletzt bearbeitet:
500 Threads zu haben erscheint mir übrigens nicht so ganz wie optimales design...
Bedenke dass bei jedem Threadwechsel, die CPU die Register leeren und neu füllen muss. Sicher gibt es etliche automatische Optimierungen, trotzdem ist es sinnvoll soetwas zu vermeiden.
 
Aufgabe ist es, einen Ordner zu überwachen und neue Dateien zu behandeln. Da sich 'move' nicht ordentlich vom filesystemwatcher behandeln lässt, bzw das Programm -'aufholen' muss, wenn es mal nicht lief, mißbraucht ich das spawning der Standard-worker. Nur können da gern mal ein paar hundert Dateien auf einmal in die queue kommen. Wie gesagt, ich hab inzwischen eine Lösung, die die Worker auf cores-1 begrenzt :)

Sent from my Nokia 6110 using Tapatalk
 
Na wenns funktioniert ist ja gut, ansonsten geht das it dem FSW relativ gut, ja bei Move muss man zugegebenermaßen etwas tricksen, insb. wenn es im Netzwerk liegt. Der einfachste Weg den ich kenne ist einfach nur die normalen onChange Events abzuhören und die ganze Änderungslogik selber zu implementieren, mit Hashes und/oder anderen Identifikationsmechanismen.
 
Hardwareluxx setzt keine externen Werbe- und Tracking-Cookies ein. Auf unserer Webseite finden Sie nur noch Cookies nach berechtigtem Interesse (Art. 6 Abs. 1 Satz 1 lit. f DSGVO) oder eigene funktionelle Cookies. Durch die Nutzung unserer Webseite erklären Sie sich damit einverstanden, dass wir diese Cookies setzen. Mehr Informationen und Möglichkeiten zur Einstellung unserer Cookies finden Sie in unserer Datenschutzerklärung.


Zurück
Oben Unten refresh