DelphiTheWorld 0 Posted March 27 Hi everybody, I'm using Delphi 12 on Windows for Desktop applications. I've an FMX project done in single threaded mode (classical without threads) with timers and I have a problem with animation of objects inside frames! The project is structured like that : A main form with 2 timers and 3 layouts (Top, Main, Bottom). 1 - The first timer is in charge to display successively TFrames regarding a process inside the layouts 2 - The second one is in charge of the standby mode management A second form with 5 timers in charge of the communication with a PLC 1 - The 5 timers have different frequencies in order to read different values of the PLC (500 ms, 1s, 1.5s, etc) In the main form, on specifics frames, I've some objects (like TArc or TRectangle, etc.) that are animated by using TFloatAnimation. My problem is that these animations are lagging. Trying to analyse the problem I made a try without timers and it seems to work smoothly but it is hard to conclude if it is only the timers! I would like to create some threads to eliminate the timers and my idea is to create one thread by frequency of reading. But when I will call the method to read from the "Execute" function of the thread, the method called will be located inside the second form in a specific class (but the method is not located in a visual component of the FMX library). So my questions are: Should I use "Synchronize" even if the method called is not a visual component ? I'm afraid of the fact that it could slow down the application as before by the timers if each thread is all the time Synchronizing to make the different read methods calls! To replace the 2 timers of the main thread, I imagined the use of 2 more threads to send events to the main form to let it know when it is needed to change of frame or going in standby mode. Is there a good idea? Is there really the good approach? I'm a little bit lost never stopping to think to do it in the better way. Many thanks to all in advance for your contributions. Share this post Link to post
weabow 6 Posted April 15 I'm not strong at threads, but have to use them due to crossplatform app. So : TThread.Synchronize is made to display something in the gui, surely. But I often prefer TThread.ForceQueue. After you have a lot of timers. In the past on Windows, that wasn't a good strategy. I'd prefer one timer with a switch. After you can use, I think, tthread.CreateAnonymousThread, but when you want it to do something to be displayed, you have to Synchronise, or ForceQueue, from this Anonymous thread. Also, if you have a variable in the main thread, and you want to change its value from Anonymous, you have to do it in a Synchronyse, from th Anonymous. And to finish, be careful of Android, which threads are a little bit differnet from the other plateforms. Hope this helps. Share this post Link to post
Remy Lebeau 1436 Posted April 16 8 hours ago, weabow said: TThread.Synchronize is made to display something in the gui, surely. But I often prefer TThread.ForceQueue. TThread.Synchronize() is not limited to just GUI work, though that is what it is commonly used for. It just serializes threads to run code though the main UI thread, nothing more. TThread.ForceQueue() is meant to be used in the main UI thread only, worker threads should use TThread.Queue() (or TThread.Synchronize()) instead. TThread.Synchronize() and TThread.Queue() bypass the internal queue when they are called in the main UI thread. TThread.ForceQueue() was added so the main UI thread can queue things up, too. 8 hours ago, weabow said: Also, if you have a variable in the main thread, and you want to change its value from Anonymous, you have to do it in a Synchronyse, from th Anonymous. Or, simply wrap the variable behind a thread-synchronization object, such as TCriticalSection, TEvent, TConditionalVariableCS, TMREWSync, TInterlock, etc. Many different ways to protect a variable from concurrent access across multiple threads. 8 hours ago, weabow said: And to finish, be careful of Android, which threads are a little bit differnet from the other plateforms. Not really. Android runs on top of Linux, so its base threading is pretty similar to other platforms. However, there are restrictions on what can and cannot be executed on the UI thread, for instance, but that is artificially enforced by Android's implementation of Java, not Linux itself. 2 Share this post Link to post