David Schwartz 426 Posted July 28, 2021 I've got a bunch of things (n=4 .. 40 or so) I want to execute in parallel because each one takes a varying amount of time (eg., 5 to 20 seconds). All are calls to the same synchronous function with different parameters. I don't know if I need a task pool or not, because they're not doing anything while waiting to complete. Upon completion they'll receive a 10k-50k packet of response data. They all have unique names, and I'd like to put them into something like a TListView to provide visual feedback to the user about their current state, eg., pending, started, and finished + a status code. I want to update a line in the TListView corresponding to each task when it changes state. And when they're ALL completed, enable a "Continue" button that can then be clicked. Looking at the parallel tasking documentation, it seems I can wait for ANY ONE of them to finish, or for ALL of them to finish. The examples I've found simply mirror this model. I want to wait for EACH ONE to finish and do something slightly different (update a different line item in a VCL control) upon their termination, then do something else (enable a button) when they've ALL finished. I'd like to find an example of this approach to study. Share this post Link to post
Fr0sT.Brutal 900 Posted July 28, 2021 No need in pool or something extra. Just create new threads, set their OnTerminate event and increase counter. In OnTerminate handler do what you need for single thread finish, decrease counter and when it reaches do overall finish. 1 Share this post Link to post
aehimself 396 Posted July 28, 2021 You also can utilize WaitForMultipleObjects. Share this post Link to post
Remy Lebeau 1394 Posted July 28, 2021 15 hours ago, David Schwartz said: I don't know if I need a task pool or not A pool would make sense only if you want to limit the number of threads that are run simultaneously. Say, you have all 40 tasks, but you only want 10 to run at a time. So you create 40 tasks and put them in a queue, and then start the first 10 tasks, and each time a task finishes then it starts the next task in the queue until the queue is empty. 6 hours ago, aehimself said: You also can utilize WaitForMultipleObjects. If you are doing the wait in the main UI thread, MsgWaitForMultipleObjects() would be a better choice, so that you can detect when the message queue has pending messages waiting to be processed. But really, you shouldn't be waiting on the tasks at all, you should let them notify you when they are finished, like @Fr0sT.Brutal described. Except maybe at app shutdown, when you need to terminate and wait on any tasks that haven't finished yet. 1 Share this post Link to post
Darian Miller 361 Posted July 31, 2021 You seem to have two main goals - do a little work after each thread completes and coordinate a bigger task once everything is done. When each thread completes you could fairly easily post a user defined windows message and have the form update the state when the message is received. For the second, more complicated synchronization issue of waiting on a varying number of threads to complete, since your total count is under 64 you could go with WaitForMultipleObjects as previously suggested. However, if your thread count might rise above that fixed limit, you may want to consider utilizing TCountDownEvent for this second task instead. Here's a blog post on it: https://www.ideasawakened.com/post/test-driving-delphi-s-tcountdownevent with corresponding example code on GitHub. 2 Share this post Link to post