Форум: "Основная";
Текущий архив: 2005.06.14;
Скачать: [xml.tar.bz2];
ВнизИспользование inherited Найти похожие ветки
← →
Mouserx (2005-05-30 15:18) [0]Есть у меня поток:
Метод Free я обьявляю так:
destructor TScriptThread.Destroy;
begin
inherited;
fFindedList.Free; {TStringList}
fIgnoreList.Free; {TStringList}
//inherited Destroy;
end;
Как я понял - Inherited вызывает обработчик предка. Где он должен стоять в моем варианте? в начале или в конце?
← →
TUser © (2005-05-30 15:21) [1]В конце
← →
Mouserx (2005-05-30 15:21) [2]
> Метод Free я обьявляю так:
Имелось ввиду деструктор Destroy.
Метод Free я использую из основного потока. И как я знаю - 2 StringList-а должны освободится именно из дополнительного потока.
← →
Sergey Masloff (2005-05-30 15:21) [3]В деструкторе в конце. В конструкторе - в начале ;-)
← →
Defunct © (2005-05-30 15:21) [4]Для Destructor"а - в конце.
Для процедур - где по логике работы будет необходим.
← →
-=XP=- © (2005-05-30 15:23) [5]Метод Free я обьявляю так:
destructor TScriptThread.Destroy;
Замечательное объявление метода Free! :)
inherited рекомендуется в конце.
Хотя, все на самом деле зависит от Ваших потребностей.
Может быть и в начале.
Частично зависит от того, где создаются объекты fFindedList и sIgnoreList: если Вас угораздило создавать их в конструкторе перед вызовом inherited Create, то и удалять их надо, скорее всего, после inherited Destroy;. По принципу FIFO :).
Но, как я уже сказал - это зависит от Вашего алгоритма и хода мыслей.
← →
Digitman © (2005-05-30 15:23) [6]
> Inherited вызывает обработчик предка
не обработчик, а просто метод
об методах-обработчиках имеет смысл говорить в контексте событий объекта, здесь же ни о каких событиях речи не идет
> Где он должен стоять в моем варианте? в начале или в конце?
где угодно.
в отрыве от остального кода говорить об этом бессмысленно
← →
TUser © (2005-05-30 15:26) [7]На самом деле, дажде если не написать Inherited, то вызов унаследованного деструктора все равно происходит. По крайней мере в D7.
← →
Digitman © (2005-05-30 15:28) [8]
> TUser © (30.05.05 15:26) [7]
> На самом деле, дажде если не написать Inherited, то вызов
> унаследованного деструктора все равно происходит. По крайней
> мере в D7.
с какого перепугу-то ?
ты может быть путаешь собственно разрушение объекта с методом-деструктором ?
← →
Mouserx (2005-05-30 15:31) [9]Хм ... тогда я ничего не понял.
Вот мой коснструктор Create:
constructor TScriptThread.Create(Sender : TObject);
begin
inherited Create(True); {Поток создаем в состоянии «Приостановлен»}
FreeOnTerminate := True; {Поток освободит ресурсы при окончании работы}
fFindedList := TStringList.Create;
fIgnoreList := TStringList.Create;
Thread := Self;
Self.Priority := tpNormal; {Стартуем с нормальным приоритетом}
Resume; {Переводим поток в состояние «Активен»}
end;
В данном случае 2 TStringList я создаю после inherited Create(True);
Т.е как я понял освобождать их надо до Inherited Destroy.
Так?
Но получается, что вызвав метод Free из основного потока - он пробежится по всему содержимому деструктора до inherited. Ну и поосвобождает 2 TSctrinList, работу с которыми я не закончил.
Их же надо освобождать именно из дополнительного потока а не из основного. Что я не так сделал и не понял?
← →
TUser © (2005-05-30 15:33) [10]> Digitman © (30.05.05 15:28) [8]
Может я чего-то не понял. Написал
destructor TForm1.Create;
begin
...
end;
без inherited. Поставил Use Debug DCUs. И отладчик зашел в деструктор предка.
← →
Defunct © (2005-05-30 15:34) [11]Mouserx (30.05.05 15:31) [9]
> Ну и поосвобождает 2 TSctrinList, работу с которыми я не закончил.
Используйте событие OnTerminate для уверенности. После обработки данных вызывайте Free.
← →
TUser © (2005-05-30 15:35) [12]> Mouserx (30.05.05 15:31) [9]
Они в дополнительном потоке и освободятся. По логике, если FreeOnTerminate = true, то не надо вызывать Free из основного потока, а надо писать Terminate;
← →
Defunct © (2005-05-30 15:36) [13]> TUser
destructor TForm1.Create; ??
← →
Mouserx (2005-05-30 15:36) [14]
> Используйте событие OnTerminate для уверенности
А будет ли это событие, если я поток трогать не буду а просто дождусь, пока он сам все сделает и выйдет?
← →
Digitman © (2005-05-30 15:38) [15]
> Написал
>
> destructor TForm1.Create;
> begin
> ...
> end;
> И отладчик зашел в деструктор предка
какую-то галиматью ты написал)
Create() - это имя конструктора класса, а не деструктора
← →
Defunct © (2005-05-30 15:38) [16]Mouserx (30.05.05 15:36) [14]
Да, это событие происходит после окончания работы метода Execute
← →
Mouserx (2005-05-30 15:42) [17]
> Используйте событие OnTerminate для уверенности. После обработки
> данных вызывайте Free
После метода Execute вызывается деструктор Destroy.
А зачем еще вызывать Free?
← →
-=XP=- © (2005-05-30 15:43) [18]Но получается, что вызвав метод Free из основного потока - он пробежится по всему содержимому деструктора до inherited
Третья заповедь: Прежде чем рубить ветку, убедитесь, что Вы на ней не сидите (С) Энциклопедия юных сурков
Thread.Teminate;
Thread.WaitFor;
Tread.Free;
← →
Digitman © (2005-05-30 15:43) [19]
> Mouserx (30.05.05 15:31) [9]
местоположение inherited в дан.ситуации сильно зависит от того, кто вызывает деструктор
← →
-=XP=- © (2005-05-30 15:47) [20]По-моему, мы сейчас обсуждаем "через какую дверь лучше всего входить в метро".
← →
Mouserx (2005-05-30 15:48) [21]
> -=XP=- © (30.05.05 15:43) [18]
Thread.Teminate;
Thread.WaitFor;
Это понятно.
Но зачем Tread.Free если поток сам освободится?
Tread.Free приведет к ошибке.
Да и насчет использования этой конструкции:
А если поток будет в состоянии ожидания Sinchronize()?
Получиться что поток ждет, пока освободится основной поток для выполнения Sinchronize() а тот в свою очередь ждет (Thread.WaitFor) пока закончит работу дополнительный поток
← →
Defunct © (2005-05-30 15:50) [22]Digitman © (30.05.05 15:43) [19]
Понимаю это так:destructor TScriptThread.Destroy;
begin
inherited;
SendMessage( <Handle окна обработчика>, <Требование обработки List"ов>, xxx, xxx);
fFindedList.Free; {TStringList}
fIgnoreList.Free; {TStringList}
end;
Но что мешает сделать так:destructor TScriptThread.Destroy;
begin
SendMessage( <Handle окна обработчика>, <Требование обработки List"ов>, xxx, xxx);
fFindedList.Free; {TStringList}
fIgnoreList.Free; {TStringList}
inherited;
end;
IMHO в деструкторе всегда inherited в конце, ничему не навредит и всегда будет работать. В крайнем случае можно засунуть inherited в finally.
← →
Mouserx (2005-05-30 15:51) [23]Digitman © (30.05.05 15:43) [19]
Задача такова. Есть дополнительный поток, в котором производяться медленные стороние вычисления.
Основной поток вызывает его используя метод Create. При этом в основном потоке в Destroy необходимо остановить и доп. потоки. Поэтому там для всех созданных доп. потоков я вызывал просто метод Free каждому.
Доп. поток, когда доделает свою работу - через метод Sinchronize() сообщить основному.
← →
Digitman © (2005-05-30 15:52) [24]
> Mouserx (30.05.05 15:48) [21]
а что, без FreeOnTerminate=True никак не обойтись ?
что мешает в нужный момент разрушить поток извне ?
← →
Defunct © (2005-05-30 15:54) [25]Mouserx (30.05.05 15:51) [23]
> Поэтому там для всех созданных доп. потоков я вызывал просто метод Free каждому.
Чревато AV ошибками на выходе из программы.
← →
Digitman © (2005-05-30 15:54) [26]
> При этом в основном потоке в Destroy
в Destroy какого класса ?
← →
Digitman © (2005-05-30 15:59) [27]
> Defunct © (30.05.05 15:50) [22]
> в деструкторе всегда inherited в конце, ничему не навредит
> и всегда будет работать
не факт.
в случаях когда разрушение объекта должно быть защищено, например, крит.секцией, поставить inherited последним вряд ли удастся
← →
-=XP=- © (2005-05-30 16:07) [28]Это понятно. Но зачем Tread.Free если поток сам освободится? Tread.Free приведет к ошибке.
При этом в основном потоке в Destroy необходимо остановить и доп. потоки. Поэтому там для всех созданных доп. потоков я вызывал просто метод Free каждому.
Вы сами себе противоречите.
← →
Mouserx (2005-05-30 16:08) [29]
> что мешает в нужный момент разрушить поток извне ?
Поток может остановится только когда сам алгоритм позволяет. в местах где он может безаварийно остановиться - я проверяю:
if Terminated then ....
Кроме 2-х StringList в потоке создаються обьекты, которые потом уничтожаються ... поэтому необходимо чтобы освобождался поток сам.
← →
jack128 © (2005-05-30 16:10) [30]Defunct © (30.05.05 15:50) [22]
IMHO в деструкторе всегда inherited в конце, ничему не навредит и всегда будет работать. В крайнем случае можно засунуть inherited в finally.
например в деструкторе предка вызываются виртуальные методы, которые ты перекрыл, а в этих методах нужен доступ к листам..
← →
Defunct © (2005-05-30 16:13) [31]Digitman © (30.05.05 15:59) [27]
типовой схемой в таких случаях всегда считал такую
destructor ...;
begin
try
CS.Enter;
try
<>
finally
CS.Leave
end
finally
inherited
end
end
опять же IMHO, из-вне выгоднее выполнить защищенное разрущение.
← →
Mouserx (2005-05-30 16:13) [32]
> Чревато 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:15) [33]jack128 © (30.05.05 16:10) [30]
гм.. да это вариант. Но, не находите, это возможно уже ошибка в проектировании, что может привести к серьезным глюкам.
← →
Digitman © (2005-05-30 16:18) [34]
> 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;
← →
Digitman © (2005-05-30 16:22) [35]
> Mouserx (30.05.05 16:13) [32]
ну вот там, в деструкторе своего класса и вызывай деструкторы потоков.
и при этом inherited в них должен ПРЕДшествовать освобождению ресурсов, занятых в конструкторах потоков и используемых в теле поточной ф-ции
← →
Mouserx (2005-05-30 16:23) [36]Кто мне может всетаки подсказать как правильно спроэктировать доп. поток и как правильно его "убивать" из вне?
← →
Mouserx (2005-05-30 16:27) [37]
> ну вот там, в деструкторе своего класса и вызывай деструкторы
> потоков.
Просто Thread.Destroy?
Не противоречит ли с [21]?
> и при этом inherited в них должен ПРЕДшествовать освобождению
> ресурсов
Т.е в начале.
← →
Defunct © (2005-05-30 16:28) [38]Mouserx (30.05.05 16:23) [36]
Попробую написать вам рабочий пример. А то рассказывать получается сложнее.
← →
Digitman © (2005-05-30 16:29) [39]
> Mouserx (30.05.05 16:23) [36]
критерия "правильности" нет.
есть критерии надежности, работоспособности, эффективности использования
посмотри демо-проект (%DELPHI%)\demos\threads\thrddemo.dpr
← →
Digitman © (2005-05-30 16:32) [40]
> Mouserx (30.05.05 16:27) [37]
> Просто Thread.Destroy?
> Не противоречит ли с [21]?
да, просто Thread.Free
нет, не противоречит, если FreeOnTerminate=False
> Т.е в начале
не обязательно.
но ДО того как ты уничтожишь ресурсы, к которым доп.поток обращается в ходе работы
Страницы: 1 2 вся ветка
Форум: "Основная";
Текущий архив: 2005.06.14;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.043 c