Forum > FPC development

"exception class 'External :?'."

(1/5) > >>

BIANCO:
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:
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:
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:
In your code you have:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---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  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---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:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---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 )

Navigation

[0] Message Index

[#] Next page

Go to full version