Jump to content

Recommended Posts

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

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.

  • Like 1

Share this post


Link to post

You also can utilize WaitForMultipleObjects.

Share this post


Link to post
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.

  • Like 1

Share this post


Link to post

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.  

 

 

CountDownEventSynchronizationPrimitive.png

  • Like 2

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×