カスタムスレッドの不正行為
-
22-12-2019 - |
質問
以下のクラスを考える:
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;
.
メインフォームが自動的に呼び出すとき、スレッドはメソッドInstanceVar := EventTitle.Create
に到達する必要があります。メソッドが実行されていない理由を理解できませんでした。アプリケーションの主な形式はまだうまく機能しますが、CreateSprite
が突然停止したり、開始しないようです。それは誤解と同様に誤解をしています。それは私の最初のマルチスレッドトライアルであり、いかなる矛盾のために申し訳ありません。誰かが私が何が悪いのかを見てもらえますか?
解決
ここでは明らかな問題がいくつかあります。修正があなたの問題を解決することが確かではありませんが、私は驚かないでしょう:
-
Execute
メソッドは、実行するのにoverride
で宣言する必要があります。これにより、報告する動作について説明します。 - あなたのデストラクタは、実行するのに
override
で宣言する必要があります。GEvent.Destroy
を実装するが、GEvent
クラスはデストラクタを宣言しないことに注意してください。そのため、質問のコードはコンパイルされません。 - スレッドクラスのデストラクタに
Terminate
を呼び出さないでください。基本クラスデストラクタTThread.Destroy
は、スレッドを終了して待ちます。Terminate
の呼び出しを解除します。 -
GEvent.Destroy
メソッドはTerminate
を隠します。それは本当に悪い練習です。私はコンパイラがこれをあなたに警告していると確信しています。あなたは警告を恐れなければなりません。スレッドのデストラクタがスレッドを中断してから、終了するのを待ちます。あなたはあなたがそれを破壊する時までにスレッドがすでに実行を終えたことを願っていました。 - すぐに再開するためだけに中断されたスレッドを作成するのは無意味です。それによって引き起こされるだろう本当の問題はありませんが。
-
TThread.Terminate
のコードは全く偽のボーガスです。GEvent.Call
に割り当てないでください。そのコードを削除する必要があります。 -
Self
へのあなたの電話はすべて間違っています。Suspend
を呼び出さないでください。予測不可能な結果があります。Suspend
への通話を削除します。
あなたが行った繰り返しエラーはSuspend
の省略です。そのキーワードは仮想メソッドをオーバーライドするために使用されます。 override
メソッドとデストラクタの場合、これらは基本クラスによって呼び出された仮想メソッドです。そのため、仮想メソッドをオーバーライドしない場合は、単に派生クラスに新しいメソッドを導入しています。そして、基本クラスが仮想メソッドを呼び出すと、新しいメソッドは実行されません。
このコードから始めることをお勧めします。
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;
.
あなたのコードのほとんどすべてを取り除きましたが、ほとんどすべてが間違っていました。
所属していません StackOverflow