![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Использование inherited
Mouserx © (2005-05-30 15:18:00)Есть у меня поток:
Метод Free я обьявляю так:
destructor TScriptThread.Destroy;
begin
inherited;
fFindedList.Free; {TStringList}
fIgnoreList.Free; {TStringList}
//inherited Destroy;
end;
Как я понял - Inherited вызывает обработчик предка. Где он должен стоять в моем варианте? в начале или в конце?
evvcom (2005-05-30 16:51:00) [21]1. Если ты хочешь грохнуть поток сразу по завершении, то проще использовать FreeOnTerminate := True;
2. Если ты собираешься использовать поток повторно, то грохать его не надо сразу. Поэтому вызов Thread.Free должен быть где-то из основного потока. А в Execute даже не выходя из цикла Suspend;
3. В любом случае доп.поток должен как-то сообщить основному, что работу он выполнил. В случае FreeOnTerminate := False; здесь из основного потока и можно вызвать Thread.Free.
Digitman (2005-05-30 16:50:00) [22]
> следом же будет вызван метод Free
тьфу ты !
не Free, а inherited Destroy предка
Digitman (2005-05-30 16:48:00) [23]
> Mouserx (30.05.05 16:42) [43]
> Т.е в конце метода Execute необходимо написать Self.Free?
да какой еще Self.Free ?
метод Free поточного объекта ты вызовешь в деструкторе своего контролирующего потоки объекта, при этом сначала в методе Terminate будет установлен флаг Terminated (его ты можешь периодически контролировать в теле Execute, и как только увидишь что он True, как можно быстрее завершай работу метода), затем будет вызван метод WaitFor (он дождется завершения работы потока как ОС-объекта) и следом же будет вызван метод Free, который приведет к разрушению потока уже как VCL-объекта
Mouserx (2005-05-30 16:42:00) [24]
> Как вызовешь Free, так и освободит.
Т.е в конце метода Execute необходимо написать Self.Free?
evvcom (2005-05-30 16:40:00) [25]
> как доп. поток освободит ресурсы сам
Освобождай в Destroy. Как вызовешь Free, так и освободит.
Mouserx (2005-05-30 16:37:00) [26]Digitman © (30.05.05 16:32) [40]
Из вне так будет хорошо работать, но как доп. поток освободит ресурсы сам, если FreeOnTerminate=False. Например когда он закончит с расчетами.
Digitman (2005-05-30 16:32:00) [27]
> Mouserx (30.05.05 16:27) [37]
> Просто Thread.Destroy?
> Не противоречит ли с [21]?
да, просто Thread.Free
нет, не противоречит, если FreeOnTerminate=False
> Т.е в начале
не обязательно.
но ДО того как ты уничтожишь ресурсы, к которым доп.поток обращается в ходе работы
Digitman (2005-05-30 16:29:00) [28]
> Mouserx (30.05.05 16:23) [36]
критерия "правильности" нет.
есть критерии надежности, работоспособности, эффективности использования
посмотри демо-проект (%DELPHI%)\demos\threads\thrddemo.dpr
Defunct (2005-05-30 16:28:00) [29]Mouserx (30.05.05 16:23) [36]
Попробую написать вам рабочий пример. А то рассказывать получается сложнее.
Mouserx (2005-05-30 16:27:00) [30]
> ну вот там, в деструкторе своего класса и вызывай деструкторы
> потоков.
Просто Thread.Destroy?
Не противоречит ли с [21]?
> и при этом inherited в них должен ПРЕДшествовать освобождению
> ресурсов
Т.е в начале.
Mouserx (2005-05-30 16:23:00) [31]Кто мне может всетаки подсказать как правильно спроэктировать доп. поток и как правильно его "убивать" из вне?
Digitman (2005-05-30 16:22:00) [32]
> Mouserx (30.05.05 16:13) [32]
ну вот там, в деструкторе своего класса и вызывай деструкторы потоков.
и при этом inherited в них должен ПРЕДшествовать освобождению ресурсов, занятых в конструкторах потоков и используемых в теле поточной ф-ции
Digitman (2005-05-30 16:18:00) [33]
> Defunct © (30.05.05 16:13) [31]
> Digitman © (30.05.05 15:59) [27]
>
> типовой схемой в таких случаях всегда считал такую
она, может, и будет типовой, если КС не является временным ресурсом, созданным самим разрушаемым объектом
create:
CS.Create;
destructor:
cs.Enter;
try
...
finally
inherited;
cs.Leave;
cs.Free;
end;
Defunct (2005-05-30 16:15:00) [34]jack128 © (30.05.05 16:10) [30]
гм.. да это вариант. Но, не находите, это возможно уже ошибка в проектировании, что может привести к серьезным глюкам.
Mouserx (2005-05-30 16:13:00) [35]
> Чревато AV ошибками на выходе из программы.
Вот пару раз пойвал AV и ломаю голову.
Как должно работать - написал в [29]
Digitman © (30.05.05 15:54) [26]
> При этом в основном потоке в Destroy
в Destroy какого класса ?
В дестрое моего класса, созданного в основном потоке, который считает данные с доп. потоков и контролирует их работу. сам он освобождается в Form.Close или когда закончил работу.
> -=XP=- © (30.05.05 16:07) [28]
Почему противоречу?
Defunct (2005-05-30 16:13:00) [36]Digitman © (30.05.05 15:59) [27]
типовой схемой в таких случаях всегда считал такую
destructor ...;
begin
try
CS.Enter;
try
<>
finally
CS.Leave
end
finally
inherited
end
end
опять же IMHO, из-вне выгоднее выполнить защищенное разрущение.
jack128 (2005-05-30 16:10:00) [37]Defunct © (30.05.05 15:50) [22]
IMHO в деструкторе всегда inherited в конце, ничему не навредит и всегда будет работать. В крайнем случае можно засунуть inherited в finally.
например в деструкторе предка вызываются виртуальные методы, которые ты перекрыл, а в этих методах нужен доступ к листам..
Mouserx (2005-05-30 16:08:00) [38]
> что мешает в нужный момент разрушить поток извне ?
Поток может остановится только когда сам алгоритм позволяет. в местах где он может безаварийно остановиться - я проверяю:
if Terminated then ....
Кроме 2-х StringList в потоке создаються обьекты, которые потом уничтожаються ... поэтому необходимо чтобы освобождался поток сам.
-=XP=- (2005-05-30 16:07:00) [39]Это понятно. Но зачем Tread.Free если поток сам освободится? Tread.Free приведет к ошибке.
При этом в основном потоке в Destroy необходимо остановить и доп. потоки. Поэтому там для всех созданных доп. потоков я вызывал просто метод Free каждому.
Вы сами себе противоречите.
Digitman (2005-05-30 15:59:00) [40]
> Defunct © (30.05.05 15:50) [22]
> в деструкторе всегда inherited в конце, ничему не навредит
> и всегда будет работать
не факт.
в случаях когда разрушение объекта должно быть защищено, например, крит.секцией, поставить inherited последним вряд ли удастся