Custom Thread misbehaving

delphi, delphi-xe3, multithreading

Solution

There are some obvious problems here. I'm not sure that fixing them will resolve your problem, but I would not be surprised:

- Your `Execute` method must be declared with `override` for it to run. This explains the behaviour that you report.

- Your destructor must be declared with `override` for it to run. Note that you implement `GEvent.Destroy` but the `GEvent` class does not declare a destructor. So the code in the question does not compile.

- Do not call `Terminate` in the destructor of a thread class. The base class destructor `TThread.Destroy` terminates and waits for the thread. Remove the call to `Terminate` in `GEvent.Destroy`.

- Your `Terminate` method hides `TThread.Terminate`. That is really bad practice. I'm sure the compiler warns you of this. You must heed the warnings. As it stands your thread's destructor suspends the thread and then waits for it to finish. You had better hope that the thread has already finished executing by the time you destroy it.

- It is pointless to create a thread suspended only to immediately resume it. Although there's no real problem that will be caused by that.

- The code in `GEvent.Call` is utterly bogus. Never assign to `Self`. You must remove that code.

- All your calls to `Suspend` are wrong. You must not call `Suspend`. It has unpredictable results. Remove the calls to `Suspend`.

A repeated error that you have made is the omission of `override`. That keyword is used to override a virtual method. In the case of the `Execute` method, and the destructor, these are virtual methods called by a base class. As such, if you do not override the virtual method, you are simply introducing a new method in the derived class. And when the base class calls the virtual method, your new method will not execute.

I suggest that you start with this code:

type
  EventTitle = class(TThread)
  private
    procedure DoSomething;
  public
    constructor Create;
    procedure Execute; override;
  end;

implementation

constructor EventTitle.Create;
begin
  inherited Create(False);
end;

procedure EventTitle.DoSomething;
begin
  ShowMessage('anything');
end;

procedure EventTitle.Execute;
begin
  Synchronize(DoSomething);
end;

I've stripped out almost all of your code, but almost all of it was wrong.

Problem

Given the following classes: ``` type GEvent = class(TThread) public procedure Terminate; procedure Call(Event : GEvent); constructor Create; procedure Execute; Override; end; TDirection = (DUp, DRight, DDown, DLeft); EventTitle = class(GEvent) private Index : Integer; Sprite : CSprite; Terminate : Boolean; procedure CreateSprite; procedure MoveCursor(Direction : TDirection); procedure RefreshCursor; constructor Create; destructor Destroy; public procedure Execute; end; implementation { GEvent } procedure GEvent.Call(Event: GEvent); begin Suspend; // inherited Terminate; Self := GEvent(Event.ClassType.Create); end; constructor GEvent.Create; begin inherited Create(True); end; destructor GEvent.Destroy; begin Terminate; inherited; end; procedure GEvent.Execute; begin // inherited; end; procedure GEvent.Terminate; begin Suspend; inherited; end; { EventTitle } constructor EventTitle.Create; begin inherited; Resume; end; procedure EventTitle.CreateSprite; begin Showmessage('anything'); end; destructor EventTitle.Destroy; begin inherited; end; procedure EventTitle.Execute; begin inherited; Synchronize(CreateSprite); Index := 0; { while not Terminated do begin if GISystem.System.Input.Trigger(KUp) then MoveCursor(DUp); if GISystem.System.Input.Trigger(KDown) then MoveCursor(DDown); end; } end; ``` When main form calls `InstanceVar := EventTitle.Create` automatically the Thread should reach the method `CreateSprite`, what weirdly is not happening. I could not figure why the method is not being executed. The main form of the application still works fine but it seems like the `EventTitle.Execute` stops abruptly or even do not start. It maight be misimplementation as well. It is my first MultiThreading trial, then sorry for any inconsistence. Can anyone see what I did wrong?

Original source