Właściwy sposób zniszczenia obiektu TThread

To pytanie może wydawać się banalne, ale mam nadzieję, że tego nie zignorujesz.
Przed zniszczeniem obiektu TThread zazwyczaj trzeba poczekać, aż zakończy się wątek zwany metodą TThread.Execute (), ponieważ tylko wtedy możemy być pewni, że na przykład obiekty zniszczone wewnątrz destruktora klasy nie będą już dostępne. Dlatego konieczne jest wywołanie Terminate, aby ustawić flagę Zakończone, aby wątek musiał sprawdzić, czy ma wyjść, czy nie, a następnie wywołać metodę WaitFor ().

Ponieważ wątek może zostać zawieszony, myślę, że dobrze jest wznowić go przed wywołaniem WaitFor, ponieważ w przeciwnym razie wątek wywołujący byłby zablokowany. A ponieważ wątek może być zawieszony wiele razy, należy go wznowić tyle samo razy, prawda?

while Suspended do
  Resume;

Jeśli wątek został utworzony w zawieszeniu, nie musimy się martwić, że metoda TThread.Execute () zostanie wywołana, gdy wznowimy wątek tylko po to, aby go zakończyć - nie będzie (proszę poprawić mnie, jeśli się mylę).

To, co stwierdziłem, sugeruje użycie następujących wierszy kodu dla każdego zwolnionego obiektu TThread:

MyThread.Terminate;
while MyThread.Suspended do
  MyThread.Resume;
MyThread.WaitFor;
MyThread.Free;

Niestety, kiedy zniszczymy naszą aplikację, która stworzyła wiele wątków, napisanie takiego fragmentu kodu dla każdego niszczonego obiektu TThread niepotrzebnie czyni kod bardzo długim, a może nawet nieprzejrzystym.

Dlatego doszedłem do wniosku, że wszystko to można umieścić w nadpisanym destruktorze klasy TThread, dzięki czemu wystarczy wywołać MyThread.Free (lub MyThread.Terminate, jeśli ustawiona jest MyThread.FreeOnTerminate) bez dbania o to, czy zniszczony obiekt jest obiektem TThread, czy nie:

destructor TMyThread.Destroy;
begin
  //if FreeOnTerminate, the calling thread cannot wait for itself
  if GetCurrentThreadId <> ThreadId then
  begin
    Terminate;
    while Suspended do
      Resume;
    WaitFor;
  end;

  {free all objects created in this class}

  inherited Destroy;
end;

Wybacz mi zadając takie podstawowe pytanie. Chciałbym jednak poznać wasze opinie na temat tego sposobu - mam nadzieję na uniwersalny sposób - niszczenia obiektów TThread. Zadaję te pytania, ponieważ dowiedziałem się z kodów moich kolegów z pracy, że zwykle używali pierwszego przykładu kodu do niszczenia takich obiektów, ale nigdy nie sprawdzali, czy oczekujące wątki nie zostały zawieszone, co uważałem za nieco niebezpieczne, jeśli wątki może zostać zawieszone gdzieś w kodzie. Dlatego starałem się znaleźć uniwersalny sposób niszczenia obiektów tej klasy, który uczyniłby kod jaśniejszym i bezpieczniejszym. Mam nadzieję, że nie pogorszyłem - co o tym myślisz?

Dziękujemy za sugestie z góry.

questionAnswers(2)

yourAnswerToTheQuestion