Этот вопрос может показаться тривиальным, но я надеюсь, что вы его не проигнорируете.
Перед уничтожением объекта TThread обычно необходимо подождать, пока поток, вызвавший метод TThread.Execute(), не завершится, поскольку только тогда мы можем быть уверены, что, например, объекты, уничтоженные внутри деструктора класса, больше не доступны. Поэтому необходимо вызвать Terminate, чтобы установить флаг Terminated, который поток должен проверить, чтобы узнать, следует ли выйти или нет, а затем вызвать метод WaitFor().
Поскольку поток может быть приостановлен, я думаю, что полезно возобновить его до вызова WaitFor, так как иначе вызывающий поток будет заблокирован. И поскольку поток может быть приостановлен несколько раз, он должен быть возобновлен столько же раз, верно?
while Suspended do
Resume;
Если поток был приостановлен, нам не нужно беспокоиться о том, что метод TThread.Execute() будет вызван, когда мы возобновим поток только для его завершения - он не будет (пожалуйста, поправьте меня, если я ошибаюсь).
Я предлагаю использовать следующие строки кода для каждого освобождаемого объекта TThread:
MyThread.Terminate;
while MyThread.Suspended do
MyThread.Resume;
MyThread.WaitFor;
MyThread.Free;
К сожалению, когда мы уничтожаем наше приложение, которое создало несколько потоков, запись такого фрагмента кода для каждого уничтожаемого объекта TThread без необходимости делает код очень длинным и, возможно, даже непрозрачным.
Поэтому я пришел к выводу, что все это можно было бы включить в сложный деструктор класса TThread, благодаря которому было бы достаточно вызвать MyThread.Free(или MyThread.Terminate, если MyThread.FreeOnTerminate установлен), не заботясь о является ли уничтоженный объект объектом TThread или нет:
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;
Простите меня, задавая такой основной вопрос. Однако я хотел бы узнать ваше мнение об этом - я надеюсь, что это универсальный способ - уничтожить объекты TThread. Я задаю эти вопросы, потому что я узнал из кодов моих товарищей по работе, что они обычно использовали первый пример кода для уничтожения таких объектов, но они никогда не использовали для проверки того, были ли ожидаемые нити, которые я считал немного опасными, если потоки может быть приостановлено где-то в коде. Поэтому я попытался найти универсальный способ уничтожения объектов этого класса, которые сделают код более понятным и безопасным. Надеюсь, я не сделал этого хуже - как вы думаете?
Спасибо за ваши предложения заранее.