سؤال

نظرا للفئات التالية:

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, ، ما هو غريب لا يحدث.لم أتمكن من معرفة سبب عدم تنفيذ الطريقة.لا يزال النموذج الرئيسي للتطبيق يعمل بشكل جيد ولكن يبدو أنه EventTitle.Execute يتوقف فجأة أو حتى لا يبدأ.وقد يكون سوء تنفيذ أيضًا.إنها أول تجربة لي لتقنية MultiThreading، لذا آسف على أي تضارب.يمكن لأي شخص أن يرى ما فعلته خطأ؟

هل كانت مفيدة؟

المحلول

هناك بعض المشاكل الواضحة هنا.لست متأكدًا من أن إصلاحها سيحل مشكلتك، لكنني لن أتفاجأ:

  1. لك Execute يجب الإعلان عن الطريقة مع override لتشغيله.وهذا ما يفسر السلوك الذي تبلغ عنه.
  2. يجب الإعلان عن المدمر الخاص بك باستخدام override لتشغيله.لاحظ أنك تنفذ GEvent.Destroy لكن ال GEvent لا تعلن الفئة عن المدمرة.لذلك لا يتم تجميع الكود الموجود في السؤال.
  3. لا تتصل Terminate في المدمر لفئة الموضوع.المدمرة الطبقة الأساسية TThread.Destroy ينهي وينتظر الموضوع.إزالة المكالمة إلى Terminate في GEvent.Destroy.
  4. لك Terminate يخفي الأسلوب TThread.Terminate.هذه ممارسة سيئة حقًا.أنا متأكد من أن المترجم يحذرك من هذا.يجب أن تستجيب للتحذيرات.أثناء وقوفه، يقوم مدمر الخيط الخاص بك بتعليق الخيط ثم ينتظر حتى ينتهي.من الأفضل أن تأمل أن يكون مؤشر الترابط قد انتهى بالفعل من التنفيذ بحلول الوقت الذي تقوم فيه بتدميره.
  5. من غير المجدي إنشاء سلسلة رسائل معلقة فقط لاستئنافها على الفور.على الرغم من عدم وجود مشكلة حقيقية من شأنها أن تسبب ذلك.
  6. الكود في GEvent.Call هو زائف تماما.لا تعين ل Self.يجب عليك إزالة هذا الرمز.
  7. جميع مكالماتك إلى Suspend مخطئون.يجب أن لا تتصل Suspend.لها نتائج غير متوقعة.إزالة المكالمات إلى Suspend.

الخطأ المتكرر الذي قمت به هو إغفال override.يتم استخدام هذه الكلمة الأساسية لتجاوز الطريقة الافتراضية.في حالة Execute الطريقة والمدمرة، هذه طرق افتراضية تستدعيها فئة أساسية.على هذا النحو، إذا لم تقم بتجاوز الطريقة الافتراضية، فأنت ببساطة تقوم بإدخال طريقة جديدة في الفئة المشتقة.وعندما تستدعي الفئة الأساسية الطريقة الافتراضية، فلن يتم تنفيذ طريقتك الجديدة.

أقترح عليك أن تبدأ بهذا الكود:

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;

لقد قمت بحذف جميع التعليمات البرمجية الخاصة بك تقريبًا، ولكن معظمها كان خاطئًا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top