"exception class 'External :?'." lazarus / 64-FPC development ---------------------------------------------------------------------- BIANCO · 2018-02-12 01:08 I am having this problem while destroying a thread. Project TesteCromis raised exception class 'External :?'. Does anyone know how to solve it? ----- I'm using a very cool cron lib from Iztok Kacin, which creates a thread for each task, I need to insert the tasks and destroy them in runtime but this error is happening. Debugging I got to this point from the Cromis.Scheduler lib, line 1087 class TScheduledEvent      {$ IFDEF FPC} RTLEventDestroy {$ ELSE} CloseHandle {$ ENDIF} (@ FTermEvent); The error appears when you pass this line. "exception class 'External :?'." The test application is on google drive, please if there was any genius that can help me I appreciate it. https://drive.google.com/file/d/1w4cIlvFW21uXEeOuiGO3JxSyGm13Lq8w/view ?usp=sharing * This code was initially for Delphi, but works on free Pascal except for this point. From what I've researched, this is apparently a stdcal or cdecl problem, but I do not know where to change it. ---------------------------------------------------------------------- rvk · 2018-02-12 08:32 I can't speak about the problem in Cromos... but I do see a very big problem with you calling Form1 elements within the threads without using Synchronize. Not only in LoadCronTab and DisplayCronInfo of the main thread but also in the DoOnScheduleStop etc of the cron threads. One rule... NEVER update a component from another form/thread in a thread without using TThread.Synchronize() or TThread.Queue() !!! (Maybe that's also the problem with this code in the library but I'm not sure. First fix that.) Try to take out all the Form1 updates and see if it works then without error. ---------------------------------------------------------------------- BIANCO · 2018-02-12 13:20 Hi, rvk, thanks! I made the fixes, first on the Main Thread to refresh the screen, but the error continued. By checking the Threads of the Cromis lib, I have seen that it uses Synchronize () or Queue () depending on the value passed in "SignalType" to execute OnScheduleEvent. To validate what you have suggested, I have commented the assignment of all the events [were just logs, but updated the screen, ok] minus the OnScheduleEvent that runs in Synchronize (). Even so, the error continues. Once again, thank you! but if you have more tips just talk. If it helps I'm sending the debug screen. ---------------------------------------------------------------------- engkin · 2018-02-12 14:19 In your code you have: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.Button3Click(Sender: TObject);begin  ThreadTeste               := TTheThread.Create(True);  ThreadTeste.FreeOnTerminate := True;  ThreadTeste.Start;end; If you set FreeOnTerminate := True then you should not touch the thread after starting it. Because the thread will free and destroy itself when it is done. Button4Click is touching the thread. More over: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TTheThread.Execute;begin  try  repeat    LoadCronTab;    DisplayCronInfo;    Sleep(5000);  until Terminated;  finally    OnTerminate(self);  end; end;OnTerminate is usually called if assigned. You are double calling it here. AND you are not checking if it is assigned. (It is *not* assigned). The logic that calls Execute (when you call start) calls OnTerminate if it is assigned. So you do not have to call it. ---------------------------------------------------------------------- engkin · 2018-02-12 14:23 Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i destructor TTheThread.Destroy;begin  if Assigned(FScheduleTaskList) then     FreeAndNil(FScheduleTaskList);   if Assigned(FKnowTasks) then    FreeAndNil(FKnowTasks);   Self.Terminate;  inherited Destroy;end; That does not make sense. Destroy is called after the terminate ( or Terminated := True ) ---------------------------------------------------------------------- rvk · 2018-02-12 14:29 Quote from: engkin on February 12, 2018, 03:23:11 pmThat does not make sense. Destroy is called after the terminate ( or Terminated := True ) Yep, these are all problems in unPrincipal.pas. But I also see a big problem in Cromis.Scheduler.pas itself (and that's the one causing the RTLEvent call problem). For instance, there is this in TScheduledEvent.Stop: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$IFDEF FPC}RTLEventSetEvent{$ELSE}SetEvent{$ENDIF}(@FTermEvent);Ok, so for FPC the RTLEvents are used. But in TScheduledEvent.Run() there is this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i FTermEvent := {$IFDEF MSWINDOWS}CreateEvent(nil, False, False, nil){$ELSE} RTLEventCreate{$ENDIF};Here, RTLEventCreate() is NOT used because FPC on Windows also has MSWINDOWS defined. There are a lot of these inconsistencies in the Cromis.Scheduler.pas. All the IFDEFs for WINDOWS, MSWINDOWS and FPC should be examined and fixed. BIANCO, where did you get the source-code from? Edit: Here is another: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$IFDEF MSWINDOWS}  Windows, Messages,Types,{$ELSE}  LMessages, LCLType, LCLIntf,{$ENDIF}Why wouldn't this be defined as: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$IFNDEF FPC}  Windows, Messages,Types,{$ELSE}  LMessages, LCLType, LCLIntf,{$ENDIF} ---------------------------------------------------------------------- engkin · 2018-02-12 14:34 @rvk: I have two posts above. You saw the second post. The immediate problem is in TTheThread.Execute where he calls OnTerminate without assigning anything to it. ---------------------------------------------------------------------- rvk · 2018-02-12 14:37 Quote from: engkin on February 12, 2018, 03:34:06 pmThe immediate problem is in TTheThread.Execute where he calls OnTerminate without assigning anything to it. I deleted the call to OnTerminate(self) in TTheThread.Execute but for me the code still crashed in TScheduledEvent.Stop;. Does the code run correctly for you (clicking Start and Stop)? B.T.W. the problem code you point to isn't even called because the problem already presents itself before TTheThread is ended. ---------------------------------------------------------------------- engkin · 2018-02-12 14:56 I did not try to compile it. But after reading your post I did the few obvious changes including changing "Stop Thread" and a quick test seemed to run. Waited a few seconds after hitting "Start Thread" then "Stop Thread" waited more. Closed the app. No crash. That does not mean the app is ok. ---------------------------------------------------------------------- rvk · 2018-02-12 15:00 Quote from: engkin on February 12, 2018, 03:56:07 pmI did not try to compile it. But after reading your post I did the few obvious changes including changing "Stop Thread" and a quick test seemed to run. Waited a few seconds after hitting "Start Thread" then "Stop Thread" waited more. Closed the app. No crash. Ok, for topicstarters information: Are you compiling and running on Windows of Linux? (I still find it strange that all those MSWINDOWS/FPC IFDEFs are really mixed up in Cromis.Scheduler.pas) ---------------------------------------------------------------------- engkin · 2018-02-12 15:05 Win32 FPC 3.0.2 I did not look outside unPrincipal. There might be problems in Cromis units as well. Let me check. ---------------------------------------------------------------------- BIANCO · 2018-02-12 15:24 Quote from: engkin on February 12, 2018, 03:23:11 pmCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i destructor TTheThread.Destroy;begin  if Assigned(FScheduleTaskList) then     FreeAndNil(FScheduleTaskList);   if Assigned(FKnowTasks) then    FreeAndNil(FKnowTasks);   Self.Terminate;  inherited Destroy;end; That does not make sense. Destroy is called after the terminate ( or Terminated := True ) engkin, rvk, Sorry, so many errors in the example, but I tried several things, I think my example was still polluted. engkin, I've removed the redundancy of the main Theread destroy but the error persists as rvk said, the problem is in the destruction of the Threads of Cromis lib. [I'll check the points pointed out by rvk] ---------------------------------------------------------------------- BIANCO · 2018-02-12 15:29 Quote from: rvk on February 12, 2018, 04:00:18 pmQuote from: engkin on February 12, 2018, 03:56:07 pmI did not try to compile it. But after reading your post I did the few obvious changes including changing "Stop Thread" and a quick test seemed to run. Waited a few seconds after hitting "Start Thread" then "Stop Thread" waited more. Closed the app. No crash. Ok, for topicstarters information: Are you compiling and running on Windows of Linux? (I still find it strange that all those MSWINDOWS/FPC IFDEFs are really mixed up in Cromis.Scheduler.pas) I use Windows 8.1 Pro - 64bit ---------------------------------------------------------------------- BIANCO · 2018-02-12 15:56 Quote from: rvk on February 12, 2018, 04:00:18 pmQuote from: engkin on February 12, 2018, 03:56:07 pmI did not try to compile it. But after reading your post I did the few obvious changes including changing "Stop Thread" and a quick test seemed to run. Waited a few seconds after hitting "Start Thread" then "Stop Thread" waited more. Closed the app. No crash. Ok, for topicstarters information: Are you compiling and running on Windows of Linux? (I still find it strange that all those MSWINDOWS/FPC IFDEFs are really mixed up in Cromis.Scheduler.pas) Yes, I noticed, however, as I said this lib was initially made in Delphi, but it should work on Lazarus / FPC. In the Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$ IFDEF FPC} and MSWindows and Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$ IFDEF MSWINDOWS} directives, both are true since I'm using Lazarus and Windows, right? I believe the event is being signaled correctly, so much so that the event is triggered, so this is working, right? Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$ IFDEF FPC} RTLEventSetEvent {$ ELSE} SetEvent {$ ENDIF} (@ FTermEvent); The original source I got with Iztok Kacim, I put it in the project source in the Cromis folder. I do not have much experience with Lazarus + FPC, I used Delphi, I thought this would be easier. ---------------------------------------------------------------------- rvk · 2018-02-12 16:02 Quote from: BIANCO on February 12, 2018, 04:56:11 pmI believe the event is being signaled correctly, so much so that the event is triggered, so this is working, right? {$ IFDEF FPC} RTLEventSetEvent {$ ELSE} SetEvent {$ ENDIF} (@ FTermEvent); That line shows that when using FPC (which we are) the RTLEventSetEvent() is used with FTermEvent. But looking at this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   TCPHandle = {$IFDEF MSWINDOWS}THandle{$ELSE}PRTLEvent{$ENDIF};and this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i     FTermEvent := {$IFDEF MSWINDOWS}CreateEvent(nil, False, False, nil){$ELSE} RTLEventCreate{$ENDIF};THandle and CreateEvent() is used because MSWINDOWS is also defined in FPC for Windows. I suspect this code (and the FPC-codes) are added for FPC under Linux. In that case it would all work out. As it is now, a THandle created by CreateEvent() will be used with the RTLEventCreate() called in .Stop. So all the {$IFDEF FPC} should be changed to {$IFNDEF MSWINDOWS} so only Windows-calls are used, or some {$IFDEF MSWINDOWS} should be changed to {$IFNDEF FPC}. It depends on the code within. (I couldn't find Cromis online anymore anywhere) ---------------------------------------------------------------------- rvk · 2018-02-12 16:08 Something like this: (I changed all IFDEFs for FPC to the MSWINDOWS counterpart so that RTLEvent isn't used anymore. Code: [Select]diff --git "a/C:\\Users\\Rik\\Downloads\\cromis original\\testeCromis\\cromis\\Cromis.Scheduler.pas" "b/C:\\Users\\Rik \\Downloads\\testeCromis\\cromis\\Cromis.Scheduler.pas" index ae75dbc..eb9d403 100644 --- "a/C:\\Users\\Rik\\Downloads\\New folder (2)\\testeCromis\\cromis\\Cromis.Scheduler.pas" +++ "b/C:\\Users\\Rik\\Downloads\\testeCromis\\cromis\\Cromis.Schedule r.pas" @@ -1068,9 +1068,9 @@ begin      FRunning := False;      // set the terminate event, so that the thread can safely exit -    {$IFDEF FPC}RTLEventSetEvent{$ELSE}SetEvent{$ENDIF}(@FTermEvent); +    {$IFNDEF MSWINDOWS}RTLEventSetEvent{$ELSE}SetEvent{$ENDIF}(FTermEvent); -    {$IFNDEF FPC} +    {$IFDEF MSWINDOWS}        // wait and block until the scheduling thread is finished        AResult := WaitForSingleObject(FSchThread.Handle, cShutdownTimeout); @@ -1084,7 +1084,7 @@ begin      {$ENDIF}      // close the event handle and free the thread -    {$IFDEF FPC}RTLEventDestroy{$ELSE}CloseHandle{$ENDIF}(@FTermEvent); +    {$IFNDEF MSWINDOWS}RTLEventDestroy{$ELSE}CloseHandle{$ENDIF}(FTermEvent);      FreeAndNil(FSchThread);      // fire the on schedule stop event But there are still some problems in your own code. For example if you exit your program you first need to end your ThreadTeste thread and wait for it to finish. Also, there could then still be calls to Form1 but that one is already up by then so they shouldn't execute if Form1 is already freed. ---------------------------------------------------------------------- BIANCO · 2018-02-12 16:19 Yes, it had a public repository, but it's off the air, the lib is larger, I've just added example to the units I use, the original contains parts of a commercial project, I'm waiting for its response to publish in a git original and put here, to see what we can do to make this lib compilable in fpc on windows and linux then. This is interesting that uses the cron mechanism similar to linux, I have not seen another equal in Pascal or Delphi. ---------------------------------------------------------------------- rvk · 2018-02-12 16:22 Here are two patch files with changes which worked for me (attached). You see I free the ThreadTeste in FormClose (which means a 5 second delay before the thread responds before closing). The ThreadTeste.Free is done in FormClose so you need to set FreeOnTerminate to false. As code: Code: [Select]--- testeCromis.org/cromis/Cromis.Scheduler.pas zo feb 11 01:56:48 2018 +++ testeCromis/cromis/Cromis.Scheduler.pas ma feb 12 17:15:50 2018 @@ -1071 +1071 @@ begin -    {$IFDEF FPC}RTLEventSetEvent{$ELSE}SetEvent{$ENDIF}(@FTermEvent); +    {$IFNDEF MSWINDOWS}RTLEventSetEvent(@FTermEvent){$ELSE}SetEvent(F TermEvent){$ENDIF}; @@ -1073 +1073 @@ begin -    {$IFNDEF FPC} +    {$IFDEF MSWINDOWS} @@ -1087 +1087 @@ begin -    {$IFDEF FPC}RTLEventDestroy{$ELSE}CloseHandle{$ENDIF}(@FTermEvent); +    {$IFNDEF MSWINDOWS}RTLEventDestroy(@FTermEvent){$ELSE}CloseHandle (FTermEvent){$ENDIF}; Code: [Select]--- testeCromis.org/unprincipal.pas zo feb 11 13:06:35 2018 +++ testeCromis/unprincipal.pas ma feb 12 17:23:45 2018 @@ -71,0 +72 @@ end; +    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction); @@ -164 +165 @@ begin -  ThreadTeste.FreeOnTerminate := True; +  ThreadTeste.FreeOnTerminate := false; @@ -173,0 +175,10 @@ end; +procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction); +begin +  if Assigned(ThreadTeste) then +  begin +    ThreadTeste.Terminate; +    ThreadTeste.WaitFor; +    ThreadTeste.Free; +  end; +end; + @@ -208 +219 @@ begin -  Self.Terminate; +  //Self.Terminate; @@ -214 +225 @@ begin -  try +  //try @@ -216,2 +227,2 @@ begin -    LoadCronTab; -    DisplayCronInfo; +    Synchronize(@LoadCronTab); +    Synchronize(@DisplayCronInfo); @@ -220,3 +231,3 @@ begin -  finally -    OnTerminate(self); -  end; +  //finally +  //  OnTerminate(self); +  //end; ---------------------------------------------------------------------- runner · 2018-02-12 17:05 Hello people. I am the original author of the Cromis library. The CRON scheduler is a part of it. So if I can help in any way, I will be glad to. Its quite some time since I used Lazarus / FPC for anything serious but still. First lets clear the IFDEFS issue. They were added quite some time ago as someone asked me for a Linux FPC support. So I added it. I don't think I tested any of it in full extent. Under Delphi and Windows the unit is tested and use in production environment daily. But looking over the IFDEFS at a glance I think they are correct. Basically the idea is to call windows API calls like SetEvent, WaitForSingleObject etc under Windows and Linux conterparts (RTL*) under Linux. So using  {$IFDEF WINDOWS} seems correct to me. Naturally it would be even better to use TEvent and other now build in cross platform objects that Delphi exposes (and I am sure Lazarus RTL has them), but I don't have time to update the code atm. Will check the code BIANCO sent me under Delphi and Lazarus to see where the issues are. ---------------------------------------------------------------------- rvk · 2018-02-12 17:21 Quote from: runner on February 12, 2018, 06:05:41 pmFirst lets clear the IFDEFS issue. They were added quite some time ago as someone asked me for a Linux FPC support. So I added it. I don't think I tested any of it in full extent. Under Delphi and Windows the unit is tested and use in production environment daily. But looking over the IFDEFS at a glance I think they are correct. Basically the idea is to call windows API calls like SetEvent, WaitForSingleObject etc under Windows and Linux conterparts (RTL*) under Linux. So using  {$IFDEF WINDOWS} seems correct to me. Yes, for Delphi under Windows and FPC under Linux the IFDEFs are fine. But for FPC under Windows it is not. For example, like I already said, the IFDEFs for MSWINDOWS and FPC are mixed (MSWINDOWS is also defined in FPC for Windows). The result is that FTermEvent is a THandle and it is created with CreateEvent (for Windows) but in .Stop there are several calls to RTLEvent because FPC is used in the define. Look for all FPC} in the source. They should NOT be there for FPC under Windows because FTermEvent is already a THandle due to the IFDEF MSWINDOWS. I've created a patch where all IFDEF FPC is changed to IFNDEF MSWINDOWS (and IFNDEF FPC in IFDEF MSWINDOWS). In that case, for FPC under Windows the Windows-events are used and for FPC under Linux the RTLEvents are used. Note: Under FPC for Windows both MSWINDOWS and FPC are defined. So use one or the other but don't mix them. If the source should run under Delphi for OSX or LINUX then you've got another problem but I don't think that's a target ---------------------------------------------------------------------- BIANCO · 2018-02-12 17:33 \ O / Your patches worked for the daughter threads correctly, now it's killing the Threas, meaning the events are not being triggered any more. I'm just having the error if I try to kill the main Thread, from TForm1, can you attach your whole code? ---------------------------------------------------------------------- runner · 2018-02-12 17:40 Quote from: rvk on February 12, 2018, 06:21:15 pmQuote from: runner on February 12, 2018, 06:05:41 pmFirst lets clear the IFDEFS issue. They were added quite some time ago as someone asked me for a Linux FPC support. So I added it. I don't think I tested any of it in full extent. Under Delphi and Windows the unit is tested and use in production environment daily. But looking over the IFDEFS at a glance I think they are correct. Basically the idea is to call windows API calls like SetEvent, WaitForSingleObject etc under Windows and Linux conterparts (RTL*) under Linux. So using  {$IFDEF WINDOWS} seems correct to me. Yes, for Delphi under Windows and FPC under Linux the IFDEFs are fine. But for FPC under Windows it is not. For example, like I already said, the IFDEFs for MSWINDOWS and FPC are mixed (MSWINDOWS is also defined in FPC for Windows). The result is that FTermEvent is a THandle and it is created with CreateEvent (for Windows) but in .Stop there are several calls to RTLEvent because FPC is used in the define. Look for all FPC} in the source. They should NOT be there for FPC under Windows because FTermEvent is already a THandle due to the IFDEF MSWINDOWS. I've created a patch where all IFDEF FPC is changed to IFNDEF MSWINDOWS (and IFNDEF FPC in IFDEF MSWINDOWS). In that case, for FPC under Windows the Windows-events are used and for FPC under Linux the RTLEvents are used. Note: Under FPC for Windows both MSWINDOWS and FPC are defined. So use one or the other but don't mix them. If the source should run under Delphi for OSX or LINUX then you've got another problem but I don't think that's a target Yes you are correct. I examined the code and there is indeed the problem. The original DEFINES were fine, but I think that I added the schedule stop procedure code later and messed up the defines. The corrected procedure should be (rvk that are basically your changes, I am just posting the full code for clarity): Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TScheduledEvent.Stop;{$IFDEF MSWINDOWS}var  AResult: Cardinal;{$ENDIF}begin  if FRunning then  begin    // dealocate the event handler    FSchThread.OnTerminate := nil;    FRunning := False;     // set the terminate event, so that the thread can safely exit    {$IFNDEF MSWINDOWS}      RTLEventSetEvent(@FTermEvent)    {$ELSE}      SetEvent(FTermEvent)    {$ENDIF};     {$IFDEF MSWINDOWS}      // wait and block until the scheduling thread is finished      AResult := WaitForSingleObject(FSchThread.Handle, cShutdownTimeout);       // check if we timed out      if AResult = WAIT_TIMEOUT then      TerminateThread(FSchThread.Handle, 0);    {$ELSE}      // wait and block until the scheduling thread is finished      RTLEventWaitFor(FSchThread, cShutdownTimeout);      FSchThread.Terminate;    {$ENDIF}     // close the event handle and free the thread    {$IFNDEF MSWINDOWS}      RTLEventDestroy(@FTermEvent);    {$ELSE}      CloseHandle(FTermEvent);    {$ENDIF}    FreeAndNil(FSchThread);     // fire the on schedule stop event    if Assigned(FOnScheduleStop) then    FOnScheduleStop(Self);  end;end;  Basically it should all be WINDOWS based and not FPC based. As I said the DEFINES were made by request from a third party and I never really tested them under FPC or Linux. With this changes there are no more exceptions and the schedule stops as it should. As for the code being cross platform, I never claimed it is If it works fine, but I only maintain the Windows Delphi version of it. I really need to put the code into public versioning system so others can contribute. Also BIANCO I checked your test example and it has several problems. You call GUI from threads without synchronize as others already stated and that is a no-go. Futhermore you don't really need your "TTheThread" class as scheduler already runs in its own thread and you have definied the callback as thread based. So in this case the schedule creates a new anonymous thread under which the task is then executed. Note that all code inside the callback (event) must also be made threadsafe, so any calls to GUI without sync are a no-go. Also you need to check how to manage threads as you have several problems there also. Not criticising, just pointing it out, as multithreading is not easy and takes a lot of practise. I am doing it for almost 10 year already (heavy multithreading and multi processing) and still get bitten by it ---------------------------------------------------------------------- BIANCO · 2018-02-12 18:09 Thankfully for the remarks, I fully agree, others have already mentioned and made the amendments. But, I did not check the Thread GUI, I property ThreadTeste: TTheThread ...... as "main thread". I will carry this functionality to a Daemon / Service so there will be no GUI, this was created to validate the features. Once again, thank you very much, even to all! especially @runner and @rvk. @Runner, your lib is great already said by email, it would be nice to come to github. ---------------------------------------------------------------------- rvk · 2018-02-12 21:32 Quote from: BIANCO on February 12, 2018, 06:33:20 pmI'm just having the error if I try to kill the main Thread, from TForm1, can you attach your whole code? I already showed you a patch of what I changed. I didn't change anything else. I didn't even use Synchronize (which you should) but that shouldn't prevent the task from running. Maybe you can show you code again. Quote from: BIANCO on February 12, 2018, 07:09:32 pmBut, I did not check the Thread GUI, I property ThreadTeste: TTheThread ...... as "main thread". ThreadTeste is NOT the main thread. The application itself (TApplication and the main form) is the main thread. Any other thread you use is another thread. Accessing components in any thread that are in other threads need to be done via Synchronize or Queue. ---------------------------------------------------------------------- BIANCO · 2018-02-12 22:49 You're right! I expressed myself poorly -------------- Of course, I'm attaching the final code. https://drive.google.com/file/d/1MJiFqibY6JvzJdrZtbmI3XnVD- HxRwwb/view?usp=sharing I think we can end this topic as resolved! I kept creating a  "ThreadTeste" as property of TForm1 because is part of the concept that I intend to use, a Thread just to monitor and inform the state of the Threads daughter to a "console". I do not know if this architecture is the best or the right one, so I'm going to use it anyway because it helps me to know exactly what is happening with the program, the logs that I send today to the memo, will be sent to a socket channel that I will use to monitor the daemon / service. If you look at the example, it was not necessary to put the OnClose of Form1 to the destruction of ThreadTeste, I kept the "Stop Thread" button, without errors, without memory leaks! The auxiliary events, OnScheduleRun, OnScheduleStop, OnScheduleAbort, OnScheduleInvalid, OnMaxEventsExecuted are not triggered inside the Synchronize, do not belong to this time and therefore had no problem in uncommenting. The current solution already caters me, in the future I will better study the management of this list of tasks including and deleting items without having to stop the "ThreadTeste", which controls the logs. I will probably put another method in the Synchronize to re-organize the list before entering the log, but this I will try to do first, its I can not get help from the forum. I loved it, you were 1000!