chmichael 12 Posted December 10, 2020 (edited) Hello, When i'm closing the application eg, after 30 seconds OTL will raise an exception with error code 1400 invalid window handle. Any ideas ? Thank you Code: var FTask1: IOmniTimedTask; FTask2: IOmniTimedTask; procedure StartTimedTasks(const Task: IOmniTask); begin FTask1 := Parallel.TimedTask.Every(1000).Execute(DoSometing1); FTask2 := Parallel.TimedTask.Every(1000).Execute(DoSometing2); end; procedure TFormApplication.FormShow(Sender: TObject); begin Parallel.Async(StartTimedTasks); end; Edited December 10, 2020 by chmichael Share this post Link to post
Davide Angeli 44 Posted December 11, 2023 I recently started using Parallel.TimedTask and now when I close the application I get the same error in completely random mode. I can't simulate the problem in a small project. I'm using D11.3 and the latest OTL version. Some idea? Share this post Link to post
Lars Fosdal 1792 Posted December 11, 2023 Do you stop the tasks and wait for completion of any running task before stopping the application? 1 Share this post Link to post
Davide Angeli 44 Posted December 11, 2023 (edited) 1 hour ago, Lars Fosdal said: Do you stop the tasks and wait for completion of any running task before stopping the application? Before posting I tried several solutions, some of these suggested in this post: According to Primoz OTL book it seems to be enough to assign the IOmniTimedTask instance to nil to get the call to Terminate(INFINITE) and Terminate should stop the task... This works perfectley in a little sample demo. In my case leads to random errors (the app is very complex). I've tried calling the Stop method and then assign the instance to nil but I get the random errors too. I've tried calling also Stop + Terminate(INFINTE) + WaitFor(INFINITE) + assigning to nil without results Edited December 11, 2023 by Davide Angeli Share this post Link to post
Tommi Prami 131 Posted December 12, 2023 12 hours ago, Davide Angeli said: Before posting I tried several solutions, some of these suggested in this post: According to Primoz OTL book it seems to be enough to assign the IOmniTimedTask instance to nil to get the call to Terminate(INFINITE) and Terminate should stop the task... This works perfectley in a little sample demo. In my case leads to random errors (the app is very complex). I've tried calling the Stop method and then assign the instance to nil but I get the random errors too. I've tried calling also Stop + Terminate(INFINTE) + WaitFor(INFINITE) + assigning to nil without results Could you run the app in debugger and put break points at the end of DoSometing1 and DoSometing2, and be sure that you exit from them cleanly? -Tee- Share this post Link to post
Davide Angeli 44 Posted December 12, 2023 2 hours ago, Tommi Prami said: Could you run the app in debugger and put break points at the end of DoSometing1 and DoSometing2, and be sure that you exit from them cleanly? It's not so easy to debug this; when I debug and put breakpoints inside threads, thanking our beloved IDE, I get often debugger freezes. In my case "DoSomething" code is a simple rest call (I use WiRL client to send data to WiRL server); the rest call is incapsulated in a try except to avoid errors. Til now my "DoSomething" was an anonymous method. Now I've changed my code and I pass a normal procedure to timedtask.execute. Things seem to going better but I don't think this was the cause of the error. Share this post Link to post
Lars Fosdal 1792 Posted December 12, 2023 If a REST call is in progress when you terminate - will the code hangup and close the REST related thread(s) ? 1 Share this post Link to post
Davide Angeli 44 Posted December 12, 2023 35 minutes ago, Lars Fosdal said: If a REST call is in progress when you terminate - will the code hangup and close the REST related thread(s) ? I rely on the fact that by calling the stop method it waits and completes any ongoing operations. When the application ends, each TimedTask is stopped and its end is awaited. But in fact, if the REST execution is asynchronous, this might still be running. I don't know how the WiRL client works at a low level. Now I'll delve deeper. Share this post Link to post
Davide Angeli 44 Posted December 12, 2023 28 minutes ago, Davide Angeli said: I don't know how the WiRL client works at a low level. Now I'll delve deeper. WiRL client seems using THTTPClient.Get and then THTTPClient.DoExecute to execute my REST operation (a PATCH). So I suppose that it is synchronous. Share this post Link to post
Lars Fosdal 1792 Posted December 12, 2023 Does this trick have any effect? HttpClient.SetRequestHeader('Connection', 'close'); from https://stackoverflow.com/questions/48321245/thttpclient-is-not-closing-connection-in-delphi Share this post Link to post
Davide Angeli 44 Posted December 12, 2023 1 hour ago, Lars Fosdal said: Does this trick have any effect? I abandoned that trail: the problem is not the REST call. I've substituted it with a sleep(1000) and I get the same random error... The problem is somewhere else. Still investigating... Share this post Link to post
Lars Fosdal 1792 Posted December 12, 2023 Do you .Free or FreeAndNil? Are you using EurekaLog or MadExcept? Share this post Link to post
Davide Angeli 44 Posted December 12, 2023 3 minutes ago, Lars Fosdal said: Do you .Free or FreeAndNil? It depends... I use both 3 minutes ago, Lars Fosdal said: Are you using EurekaLog or MadExcept? I'm using madExcept Share this post Link to post
Lars Fosdal 1792 Posted December 12, 2023 I use EL, so I can't really opinionate on MadExcept. It is very rare that it gives me no clue to the callstack for exceptions caused by dangling pointers, but when desperate, I've turned to using a FreeAndNil overload to set the pointers to a recognizable value, $DEAD0001 and so forth, and logging the line where I set the respective ptr values to at least find a hint to the context that is trying to use it. Problems like these can be a pain to find. Another alternative would be to try with regular threads to see if the problem persists - if it doesn't, it might be that you can attribute it to something OTL specific? 1 1 Share this post Link to post
Davide Angeli 44 Posted December 12, 2023 I spent some time to deep analize the MadExcept callstack and I discovered that the thread in exception was created by another thread not even executing (I can't find his "father" in the thread list reported by madExcept). Now I've rearranged same things in the steps involved in the app terminating phase to avoid this; I've also moved the IOmniTimedTask instance as a global variable to avoid strange dependencies. Now I cannot reproduce the error. So OTL seems working fine as usual! It's always a mess working with threads! Share this post Link to post
Lars Fosdal 1792 Posted December 13, 2023 Usually a mess we create ourselves 🙂 It may be that the dead thread raising the exception was trying to use an already disposed reference in it's final moments. 1 1 Share this post Link to post
Davide Angeli 44 Posted December 13, 2023 29 minutes ago, Lars Fosdal said: Usually a mess we create ourselves 🙂 True!!! Thanks for help! 1 Share this post Link to post