System.Threading.ThreadPool
-
Hi,
ich hab ein Kommandozeilenprogramm, welche etliche Bilder generiert. Und da dachte ich mir dass es insbesonder in Hinsicht auf SMP-Systeme cool wäre, wenn ich mehrere Threads laufen lasse, die sich dann jeweils aus einem synchronisierten Queue nach und nach die Informationen der zu generierenden Bilder rausholen und diese dann generieren.
Ich bin beim darauf folgenden durchforsten des System.Threading namespaces auf die Klasse ThreadPool gestoßen. Mein Frage ist, ob diese Klasse für solche Anwendungen zu empfehlen ist? Ich habe nämlich so leicht den Eindruck dass die ThreadPool-Klasse eher für Server-Anwendungen ausgelegt ist, u.A. da alle ihre Threads als Background-Thread erstellt werden, was bei einer Anwendung wie meiner aber dazu führt, dass die Anwendung beendet wird bevor der Queue vollständig abgearbeitet ist. Dies könnte ich natürlich verhindern in dem ich System.Threding.Thread.CurrentThread.Suspend() in der Main-Methode aufrufe oder zu Beginn aller Methoden die vom ThreadPool aufgerufen werden, System.Threding.Thread.CurrentThread.IsBackground auf false setze, aber gibt es da vielleicht auch elegantere Möglichkeiten? Oder sollte ich für meinen Anwendungsfall besser System.Threading.Thread direkt ohne System.Threading.ThreadPool verwenden?
Gruß
Schrankwand
-
Ich hab nun eine saubere Lösung gefunden, die die Threads zwar nach wie vor im Hintergrund lässt aber den Ausgangsthread so lange blockt bis die Threads im Threadpool alle abgearbeitet sind.
class ButtonImageGenerator { private ButtonInfoQueue _buttonInfoQueue; public ButtonImageGenerator(ButtonInfoList buttonInfoList) { _buttonInfoQueue = new ButtonInfoQueue(buttonInfoList); } public void GenerateAll() { int numThreads = Environment.ProcessorCount + 1; ManualResetEvent[] waitHandles = new ManualResetEvent[numThreads]; for (int i = 0; i < numThreads; i++) { waitHandles[i] = new ManualResetEvent(false); ThreadPool.QueueUserWorkItem(new WaitCallback( this.imageCreationThread), waitHandles[i]); } WaitHandle.WaitAll(waitHandles); } private void imageCreationThread(object stateInfo) { ManualResetEvent waitHandle = (ManualResetEvent)stateInfo; // TODO: Bilder generieren waitHandle.Set(); } }