Jud 1 Posted November 23 I have a multitasking program that has been running for weeks, but now I'm having problems adding WaitForAll to do some things when all tasks have been finished. First, some minor problems when I add WaitForAll: the main form is no longer responsive - I can't drag it or close it. Mainly though, are problems with updating the screen. Each task has a memo that it updates occasionally. Also, there are labels for the elapsed time and estimated remaining time. These work without WaitForAll but when WaitForAll is added, the program locks up if it tries to write to a memo or change the caption of a label. I know that these aren't thread safe, but they work if WaitForAll isn't in the program. Is there an easy way to get these to work? Share this post Link to post
eivindbakkestuen 47 Posted November 23 Use a separate "master" thread to call WaitForAll. Are you already using TThread.Synchronize for the memo updates? Share this post Link to post
Jud 1 Posted November 23 So do I need to put all of the stuff where the tasks are called and WaitForAll into a thread, or just WaitForAll? I've tried the memo updates with and without TThread.Synchronize. Share this post Link to post
Remy Lebeau 1421 Posted November 23 (edited) TTask.WaitForAll() is a blocking function. If you call it in the main thread, the main message loop will be blocked. That means no UI updates, no TThread.Synchronize() or TThread.Queue() executions, nothing until the wait is finished. There are some simple solutions: You could just call WaitForAll() in a separate thread, not in the main thread. If you must call WaitForAll() in the main thread, then call it in a loop with a short timeout. Each time it times out, call Application.ProcessMessages(). Each time a task is finished, stop waiting on that task. Stop the loop when there are no more tasks to wait on. Edited November 23 by Remy Lebeau Share this post Link to post
Jud 1 Posted November 24 Thanks. I don't think that it must be called in the main thread. Share this post Link to post
Jud 1 Posted November 26 (edited) On 11/23/2024 at 1:31 AM, Remy Lebeau said: TTask.WaitForAll() is a blocking function. If you call it in the main thread, the main message loop will be blocked. That means no UI updates, no TThread.Synchronize() or TThread.Queue() executions, nothing until the wait is finished. There are some simple solutions: You could just call WaitForAll() in a separate thread, not in the main thread. Putting WaitForAll in a tThread.synchronize has the same problem. Is that what you meant? Edited November 26 by Jud Share this post Link to post
Remy Lebeau 1421 Posted November 26 3 hours ago, Jud said: Putting WaitForAll in a tThread.synchronize has the same problem. Is that what you meant? No, that is not what I meant. Calling TThread.Synchronize() in the main thread will just call the specific procedure directly, as if Synchronize() were not being used at all. What I actually meant is calling WaitForAll() inside of TThread.CreateAnonymous() or TTask.Run(), for instance. Share this post Link to post