Aamgian 2 Posted March 17, 2021 (edited) Hello, simple code that I made: TThread.CreateAnonymousThread(procedure begin TThread.Synchronize(nil, procedure begin HeaderLabel.Text := 'My Job'; end); end).Resume; when the target Android 64bit compile, using the application resume runs smoothly. Meanwhile, if you use Start to call the thread, error message will appear "cannot call start on a running or suspended thread" TThread.CreateAnonymousThread(procedure begin TThread.Synchronize(nil, procedure begin HeaderLabel.Text := 'My Job'; end); end).Start; this case only happened on some android devices target android 64bit, but if the target is 32bit the error message does not appear. has anyone experienced something similar? and what is the solution? device with sdk 30. Thank you Edited March 17, 2021 by Aamgian Share this post Link to post
Der schöne Günther 316 Posted March 17, 2021 Just as an information, here is what the documentation says about CreateAnonymousThread(..): Quote This thread is created as suspended, so you should call the Start method to make the thread run. The thread is also marked as FreeOnTerminate, so you should not touch the returned instance after calling Start. That directly contradicts your error message Quote cannot call start on a running or suspended thread Strange. Share this post Link to post
Fr0sT.Brutal 900 Posted March 17, 2021 Btw, thread.Resume is considered bad practice and deprecated since XE Share this post Link to post
Aamgian 2 Posted March 17, 2021 3 hours ago, Der schöne Günther said: Just as an information, here is what the documentation says about CreateAnonymousThread(..): That directly contradicts your error message Strange. precisely because I found something strange I asked, some friends did not believe what I was experiencing. I'll send you a video clip so you can see it. Share this post Link to post
Aamgian 2 Posted March 17, 2021 3 hours ago, Fr0sT.Brutal said: Btw, thread.Resume is considered bad practice and deprecated since XE therefore I am looking for a way to solve this problem so that I can use Start. Share this post Link to post
David Heffernan 2345 Posted March 17, 2021 7 minutes ago, Aamgian said: precisely because I found something strange I asked, some friends did not believe what I was experiencing. I'll send you a video clip so you can see it. I don't think @Der schöne Günther was doubting you, just noting that what you were doing seemed correct. Can you make an MCVE and submit a report to Quality Portal? Share this post Link to post
Aamgian 2 Posted March 17, 2021 6 minutes ago, David Heffernan said: I don't think @Der schöne Günther was doubting you, just noting that what you were doing seemed correct. Can you make an MCVE and submit a report to Quality Portal? sorry if I respond wrongly to what was conveyed by @Der schöne Günther, i will try to make report to Quality Portal, I am trying to ask here, maybe someone has experienced something similar. vide-cap.mp4 Share this post Link to post
Remy Lebeau 1396 Posted March 17, 2021 I don't have the source for the latest version to look at, but in XE3 (the last version I do have source for), that specific error message only occurs under these conditions: - (Windows only) calling Start() on a running thread, or a thread that has had Suspend() called on it more than once before Start(). - calling Start() on a thread that has already finished, but not been destroyed yet - calling Start() on a thread created by reading TThread.CurrentThread in a thread context that is not owned by a TThread. None of those conditions apply to your TThread.CreateAnonynousThread() example. Calling Start() on such a thread is absolutely the correct thing to do. So this has to be a bug that Embarcadero has introduced in a recent version and will have to fix. Share this post Link to post
Aamgian 2 Posted March 17, 2021 2 hours ago, Remy Lebeau said: I don't have the source for the latest version to look at, but in XE3 (the last version I do have source for), that specific error message only occurs under these conditions: - (Windows only) calling Start() on a running thread, or a thread that has had Suspend() called on it more than once before Start(). - calling Start() on a thread that has already finished, but not been destroyed yet - calling Start() on a thread created by reading TThread.CurrentThread in a thread context that is not owned by a TThread. None of those conditions apply to your TThread.CreateAnonynousThread() example. Calling Start() on such a thread is absolutely the correct thing to do. So this has to be a bug that Embarcadero has introduced in a recent version and will have to fix. I have tried using Samsung and Xiaomi brand devices with SDK 30 but this error does not occur. is there a role for the device in causing this to happen? as a note the device with the Vivo brand that I use is the latest release. Share this post Link to post
Remy Lebeau 1396 Posted March 18, 2021 4 hours ago, Aamgian said: is there a role for the device in causing this to happen? The device should not matter, no. This is strictly an RTL error message that TThread.Start() raises if it can't resume a suspended thread, either because the thread is not allowed to resume (e, it is already finished), or the OS failed to resume the thread properly. Hard to say for sure what is going on without seeing the latest source code for TThread. Share this post Link to post
Aamgian 2 Posted March 18, 2021 50 minutes ago, Remy Lebeau said: The device should not matter, no. This is strictly an RTL error message that TThread.Start() raises if it can't resume a suspended thread, either because the thread is not allowed to resume (e, it is already finished), or the OS failed to resume the thread properly. Hard to say for sure what is going on without seeing the latest source code for TThread. I replaced all CreateAnonynousThread in my project with ITask and all works fine. thank you procedure THeaderFooterForm.Button1Click(Sender: TObject); var aTask: ITask; begin aTask := TTask.Create( procedure begin TThread.Synchronize(TThread.Current, procedure begin HeaderLabel.Text := 'My Job'; end); end); aTask.Start; end; Share this post Link to post
Rollo62 536 Posted March 19, 2021 Not sure about waht you need to do, TL;DR; but why not exchange TThread.Synchronize(TThread.Current, to TThread.Queue(TThread.Current, For a simple notification in the UI, like a Label text, that should be good enough, and decouples much better. 1 Share this post Link to post
Remy Lebeau 1396 Posted March 19, 2021 12 hours ago, Rollo62 said: For a simple notification in the UI, like a Label text, that should be good enough, and decouples much better. If the sole purpose of the thread is just to delay a UI notification, then TThread.ForceQueue() would be better, no thread needed at all: procedure THeaderFooterForm.Button1Click(Sender: TObject); begin TThread.ForceQueue(nil, procedure begin HeaderLabel.Text := 'My Job'; end ); end; 1 Share this post Link to post
Aamgian 2 Posted March 20, 2021 On 3/20/2021 at 3:39 AM, Remy Lebeau said: If the sole purpose of the thread is just to delay a UI notification, then TThread.ForceQueue() would be better, no thread needed at all: procedure THeaderFooterForm.Button1Click(Sender: TObject); begin TThread.ForceQueue(nil, procedure begin HeaderLabel.Text := 'My Job'; end ); end; The code that I will use is actually a lot more, especially for doing the calculation process and making requests to the server. thank you for the advice you give. Share this post Link to post