Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.06.14;
Скачать: CL | DM;

Вниз

Использование 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;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.028 c
4-1114528271
Виталик
2005-04-26 19:11
2005.06.14
Проблема с запуском программы от лица другого пользователя


14-1116326649
Андрей Жук
2005-05-17 14:44
2005.06.14
Free Pascal 2.0


14-1116589520
Piter
2005-05-20 15:45
2005.06.14
Глюк со SmartFTP


1-1116993255
kilop
2005-05-25 07:54
2005.06.14
Клавишалов


1-1116949818
Karlson
2005-05-24 19:50
2005.06.14
Как Hintу в Comboboxе присвоить текущее активное значение?