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?
There are some obvious problems here. I'm not sure that fixing them will resolve your problem, but I would not be surprised:
Execute method must be declared with override for it to run. This explains the behaviour that you report.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.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.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.GEvent.Call is utterly bogus. Never assign to Self. You must remove that code.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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With