Question

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?

Was it helpful?

Solution

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

  1. Your Execute method must be declared with override for it to run. This explains the behaviour that you report.
  2. 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.
  3. 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.
  4. 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.
  5. 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.
  6. The code in GEvent.Call is utterly bogus. Never assign to Self. You must remove that code.
  7. 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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top