OK here's a question:
I have a program that batch manipulates a few thousand images (cropping and resizing). I use ThreadPool and have the worker threads do all the image processing, and that works fine.
My main question is how to signal that the work is complete -- that is, some way I know that every thread in the queue has finished. Ideally I'd like a particular thread to wait until every worker thread was finished, and then resume execution. Effectively my program has a GUI thread, a thread that recurses over folders seeking images, and then worker threads which process the images that are found. I'd like that second thread (the recursing thread) to suspend once it's fully recursed, and not continue execution until all worker threads were done.
Now I know I could use a ManualResetEvent, and then WaitForAll on it -- this is how a lot of example code works. This isn't all that great for me because:
1. That array could be tens of thousands of entries (maybe a problem, maybe not, I dunno),
2. My worker threads are created before I know a final count of how many worker threads there will be. As such, I wouldn't know how large of an array to make.
OK I think I came up with a solution, I guess you can evaluate how it works:
* I create a private static ManualResetEvent, and a static accessor to retrieve it.
* I create a private static counter of threads.
* In my PoolQueue() function, which adds a thread to the pool queue, just prior to queueing the thread, it does:
* My entire worker thread function is in a try... finally, with the finally being:
So then, after my directory traversal thread finishes adding worker threads, it can just wait for this event.
if (workers <= 0) mre.Set();
Seems like a problem that you'd have to solve a different way.
I would probably implement another thread:
- GUI Thread
- Recursive Find-Files Thread
- Processing Manager thread
- Worker Thread(s)
The find-files thread builds a linked list, and the Process Manager thread takes items in the linked list, assigns them to a worker thread, and when there are no available worker threads, waits for the first event to finish, then starts another worker thread off with the next image. That way you only need one event per worker thread, easy to count and no problems with the limits [if any] of the number of events needed.