Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Исключение в деструкторе треда при попытке протрассировать его [D5, Win2k]


Fktrc ©   (2005-03-04 09:54:00) 

Завершаю потоки при закрытии приложения
Содержание деструктора


destructor TItemThread.Destroy;
begin
  Terminate;
  SetEvent(FStopEvent);
  WaitFor;
  CloseHandle(FStopEvent);
  DeleteCriticalSection(...);
  inherited
end;


После остановки на бряке в этом деструкторе(точку можно ставить в нем где угодно) нажатие F7 F8 дает эксцепшен Access Violation и иногда EExternalException (точное название не помню).
Причем, если точку останова в деструкторе не ставить, отрабатывает без исключений и при запуске из среды, и при самостоятельном запуске.

Этот же деструктор при завершении потока НЕ при закрытии приложения трассируется без исключений...

Два вопроса
- почему так происходит?
- стоит ли переходить на OnTerminate?


Eraser   (2005-03-04 13:07:00) [1]

Digitman ©

Ну да, в плане хэндлов я легка перегнул, т.к. в основном это хэндля синхронизирующих объектов, которые используют другие потоки...
Но что касается внутренних объектов потока, то лучше [6].


Digitman   (2005-03-04 12:38:00) [2]


> Eraser ©   (04.03.05 11:38) [6]


в ряде случаев вариант с созданием/уничтожением объектов не иначе как в Execute() (и искл-но там же - работой с ними) попросту не удобен ... или недопустим по логике ...

зачастую требуется иметь УЖЕ созданный или УЖЕ уничтоженный объект ВНЕ зависимости от того, работает ли доп.трэд как ОС-объект (которому так же по логике требуется обращение к объекту) или же он приостановлен/терминирован

так что никаких четких рекомнедаций к тому, где создавать или уничтожать объект, нет и быть не может - все зависит от конкретной сквозной логики


Eraser   (2005-03-04 11:38:00) [3]

Fktrc ©

имхо лучший вариант проведения удаления разных объектов и хендлов (финализации) осуществлять сразу за основным циклом в OnExecute.


Digitman   (2005-03-04 11:29:00) [4]


> Fktrc ©   (04.03.05 11:26) [4]


> зияющий провал в знаниях о многопоточности


"Эт точно !" (с) Федор Сухов

)


Fktrc   (2005-03-04 11:26:00) [5]

Мда... маразм крепчал, шиза косила наши ряды...

Спасибо всем. Буду искать свой глюк. Тем более что, как видно, тут не просто глюк, а зияющий провал в знаниях о многопоточности...


Digitman   (2005-03-04 10:18:00) [6]

destructor TItemThread.Destroy;
begin
 EnterCriticalSection(...);
 try
  if GetCurrentthreadId <> MainThreadId then
   PostThreadMessage(ThreadId, WM_QUIT, 0, 0);
  inherited;
 finally
  LeaveCriticalSection(...);
  DeleteCriticalSection(...);
 end;
end;

procedure TItemThread.Execute;
begin
..
 while not Terminated GetMessage(..) do
  begin
   ...
  end;  
..
end;


Digitman   (2005-03-04 10:10:00) [7]


> почему так происходит?


мало ли почему ... например при более чем однократном вызове деструктора со стороны более чем одного трэда .. смотрю, ты крит.секцию пользуешь - а ведь явно некорректно пользуешь ее !

да и вообще - код деструктора выглядит по меньшей мене странно, если не сказать подозрительно ..


> - стоит ли переходить на OnTerminate?


а с какого боку тут OnTerminate ?
это просто событие, извещающее о том что исполнение метода Execute() на сей момент успешнозавершено .. к тому же вызов обработчика OnTerminate синхронизирован с трэдом, Ид которого хранится в MainThreadId


Erik1   (2005-03-04 10:05:00) [8]

У тебя странная вещь написана зачем тебе Terminate и  SetEvent(FStopEvent) одновремено? По событию StopEvent делаей выход из execute. И ходелось бы увидеть твой метод execute, каким образом ты ожидаеш событие, на какой строчке происходит exception, какя процедура вызвала Destroy(Free), стек вызовов также приведи.


Наверх

Титульная страница Поиск, карта сайта Написать письмо