[Lazarus] Thread finalization

Sven Barth pascaldragon at googlemail.com
Wed Sep 21 14:55:06 CEST 2011


Am 21.09.2011 14:31, schrieb Leonardo M. Ramé:
> I'm having a rough time with Threads.
>
> When my app starts, it creates an instance of a TThread that loads a
> bunch of images. That TThread instance can be destroyed in two ways:
>
> 1) When the loading finishes.
> 2) When the user closes the app while loading.
>
> In case 2, I destroy the thread using this code:
>
>    if Assigned(FMyThread) then
>    begin
>      FMyThread.Terminate;
>      while not FMyThread.Finished do
>        CheckSynchronize(100);
>      FreeAndNil(FMyThread);
>    end;
>
> This works ok.
>
> Now, in case 1, I thought that I should assign an OnTerminate event to
> the thread, then destroy it, but it doesn't work as expected. The app
> gets locked on my thread destroy event:
>
>    procedure TForm1.Createthread;
>    begin
>      FMyThread := TMyThread.Create;
>      FMyThread.OnTerminate := @ThreadDestroyEvent;
>      FMyThread.Start;
>    end;
>
>    procedure TForm1.ThreadDestroyEvent(Sender: TObject);
>    begin
>      FMyThread.Free;
>    end;
>
>    destructor TMyThread.destroy;
>    begin
>      // destroy internal objects
>      inherited destroy; //<-- The app gets locked here!!
>    end;
>
> Why is this happening?, am I doing something wrong?.
>

I don't know whether this will solve your error, but two things of which 
I don't know whether they are known to you:
1. Calling "Terminate" will not kill the thread, it just sets the 
"Terminated" property to true, so you must check for yourself inside 
"Execute" whether your Thread should stop
2. The event you assigned to "OnTerminate" will only be called if you 
call "DoTerminate" inside the thread (the event will be called using 
Synchronize).

You might also want to take a look at the property "FreeOnTerminate" 
which tells the thread to free itself once "Execute" returns.

Regards,
Sven




More information about the Lazarus mailing list