Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.04 c
8-1109614208
Tirex
2005-02-28 21:10
2005.06.14
png с альфа каналом на кнопке toolbar а


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


14-1117021788
Андрей Жук
2005-05-25 15:49
2005.06.14
Вопрос по С++


3-1115474287
eLVik
2005-05-07 17:58
2005.06.14
Отличить ключевое поле от обычного (ADO)


1-1117434043
Lenochka
2005-05-30 10:20
2005.06.14
Как удалить форму?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский