Перервати виконання потоку (TThread)

Працює потік тривалий час і якщо закрити програму до закінчення роботи потоку виходить помилка (з потоку формується список TList Synchronize(SynhroList) ). Що краще: чекати на виконання потоку чи перервати? А якщо перервати те, як безпечно це зробити (з перевіркою на існування потоку)?

Потік створюється, на кожен випадок формування списку, так: mFScaner := TFScaner.Create(True); mFScaner.FreeOnTerminate := true; mFScaner.Priority := tpNormal; mFScaner.Resume;

> Що краще: чекати на виконання потоку чи перервати?

краще якщо доп.потік самостійно завершить своє виконання за командою основного потоку. а щоб він це зробив якнайшвидше, у методі TThread.Execute можна циклічно і якнайчастіше перевіряти стан прапора TThread.Terminated (при створенні доп.потоку він скинутий і буде зведений як тільки якийсь потік викличе метод TThread.Terminate), і як тільки буде знайдено зведений стан прапора негайно завершувати виконання циклу з подальшим завершенням роботи TThread.Execute

Thread.Terminate; Thread.WaitFor; Thread.Free;

приклад у [4] з урахуванням FreeOnTerminate = True загрожує "граблями".

бо немає жодної гарантії, що на момент Thread.WaitFor об'єкт ще існує - він цілком міг бути вже і знищений у період між Thread.Terminate і Thread.WaitFor

FreeOnTerminate = True у ряді його застосувань - небезпечний підхід до знищення тред-об'єктів

я б рекомендував не зводити цей прапор, а просто в потрібний момент ЯВНО викликати Thread.Free, за умови, що алгоритм у тілі Execute коректно реагує на стан прапора Terminated

FreeOnTerminate = True у ряді його застосувань - небезпечний підхід до знищення тред-об'єктів

я б рекомендував не зводити цей прапор, а просто в потрібний момент ЯВНО викликати Thread.Free, за умови, що алгоритм у тілі Execute коректно реагує на стан прапора Terminated

Що може бути небезпечного у FreeOnTerminate все одно в результаті викликається. if FreeThread then Thread.Free; Причому не з самого класу, а з глобальної процедури потоку.

> Що може бути небезпечного у FreeOnTerminateТе, що після присвоєння цього прапора від змінної класу потоку маніпуляції [4] так само як і інші маніпуляції можуть призвести до непередбачуваних наслідків, т.к. потік може сам себе звільнити після завершення, а завершиться може вже до виконання цих маніпуляцій.

Якщо конструкторі потоку св-ву FreeOnTerminate присвоюється True, то взагалі взагалі оголошувати змінну класу потоку. Тобто. не Thread: = TmyThd.Create; , а просто TmyThd.Create;

Зрозуміло, якщо потік гарантовано не завершиться до виконання певної умови, то можна використовувати змінну класу потоку до виконання цієї умови, але простіше не використовувати FreeOnTerminate в цьому випадку.

> Що може бути небезпечного у FreeOnTerminate

сам по собі він анітрохи не небезпечний. Але якщо потрібно якийсь контроль за роботою потоку після його створення через його ж методи, і при цьому не вжито жодних заходів щодо повідомлення про завершення потоку, то заробити AV в якийсь момент часу при зверненні до св-ву/методу вже неіснуючого об'єкта (адже сам себе руйнує !) - це запросто

> Тому потрібно ввести в тілі циклу додаткову перевірку > начебто if Terminated then ExitТи забув згадати кілька "якщо". Загалом ЦЕ зовсім необов'язково.

> сам пособі він анітрохи не небезпечний. > але якщо потрібний контроль за роботою потоку після > його створення через його методи, і при цьому не прийняті > ніякі заходи щодо повідомлення про завершення потоку, то заклопотати > AV у якийсь час при зверненні до св-ву/методу > вже неіснуючого об'єкта (адже сам себе руйнує > !) - це запросто

Але це вже називається дикий покажчик. З таким же успіхом можна вбити потік і з якогось іншого потоку. А в третьому звернутися до вказівника на вже не існує, що, можливо, призведе до AV.