![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Подскажите почему я не могу освободить поток [D7, XP, 2003]
KyRo © (2006-12-01 11:30:00)Я создаю поток
StatusATMT:=TStatusATMThread.Create(False);
constructor TStatusATMThread.Create(CreateSuspennded: Boolean);
begin
inherited Create(CreateSuspennded) ;
// Создаем сервер
ServerS:=TServerSocket.Create(nil);
ServerS.OnClientError:=ServerClientError;
ServerS.OnClientRead:=ServerClientRead;
ClientS:=TClientSocket.Create(nil);
ClientS.OnError:=ClientError;
ClientS.OnConnect:=ClientConnect;
ClientS.ClientType:=ctNonBlocking;
//priority:=tpLowest;
Resume;
end;
В EXECUTE есть соответственно цикл который запускает сокет сервер и клиент и начинает работать по сети с клиентами
While not Terminated do
begin
ATML:=TStringList.Create;
{Запрашиваем список ай пи адресов клиентов которых надо опросить}
if LoadATMList(ATML) =False
then
begin
ATML.Free;
Terminate;
end;
{Запускаем опрос}
For i := 0 to ATML.Count -1 do
begin
{Запускаем сервер}
ServerS.ServerType:=stNonBlocking;
ServerS.Port:=50018;
ServerS.Active:=True;
и.т.д
При выходе из этого цикла (то есть в конце экзекют) я освобождаю сервер и клиент
ServerS.Free;
ClientS.Free;
ATML.Free;
И вот из основной программы я пытаюсь его освободить и на этом программа залипает !!!
StatusATMT.Terminate;
StatusATMT.Free;
StatusATMT -это глобальная переменная С типом TStatusATMThread
Подскажите из за чего это может происходить ?
KyRo (2006-12-01 16:33:00) [1]ок спасибо
Сергей М. (2006-12-01 16:26:00) [2]ActiveX
KyRo (2006-12-01 16:23:00) [3]
CoInitialize(nil);
try
.. работа с АДО, от начала и до конца ...
finally
CoUninitialize;
end;
Я щас начал добовлять эту инициализацию пишет не известный идентификатор ! В каком юните находятся эти функции ?
Anatoly Podgoretsky (2006-12-01 16:02:00) [4]> sniknik (01.12.2006 11:48:08) [8]
> убери пока больше никто не видел...
Поздно.
KyRo (2006-12-01 16:00:00) [5]Все сделал просто надо было выйти из цикла и вызвать Break и раставить еще по некоторым процедурам exit как тут советовали.
всем спасибо
Anatoly Podgoretsky (2006-12-01 16:00:00) [6]> clickmaker (01.12.2006 11:34:01) [1]
> а почему не просто Break?
Что бы выполнить еще раз цикл I
Сергей М. (2006-12-01 15:28:00) [7]В любом случае пара CoInitialize/CoUninitialize не помешает.
KyRo (2006-12-01 15:07:00) [8]
> Это не модули, а юниты.
>
> Значит один из этих юнитов использует ComObj в uses.
> Либо где-то среди них явно вызывается сабж.
> Только так, третьего не дано.
Ну в любом случае если вы говорите что так будет правильно, сделаю так.
Сергей М. (2006-12-01 14:18:00) [9]
> KyRo (01.12.06 14:05) [31]
> Нету его вот все модули
Это не модули, а юниты.
Значит один из этих юнитов использует ComObj в uses.
Либо где-то среди них явно вызывается сабж.
Только так, третьего не дано.
KyRo (2006-12-01 14:05:00) [10]
> ComObj
>
> Скорей всего у автора этот юнит задействован, раз он миновал
> засаду с исключением по этому поводу.
Нету его вот все модули
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DBCtrls, fDBCtrls, Grids, ValEdit, ExtCtrls, ComCtrls,
Buttons, CheckLst, fCtrls, ImgList, ParsM, IniFiles, Registry, Menus,
DBGrids, Tray ,ADOConEd ,ADODB ,ClipBrd, AppEvnts ,CopyFile, ScktComp,
Gauges, Winsock, TrayIconU ,ShellApi,StatusATMThread,db;
> icWasya © (01.12.06 13:59) [28]
> а как вот после вот этого
> if LoadATMList(ATML) =False
> then
> begin
> ATML.Free; // <<==-- вот это
> Terminate;
> end;
> выполняется вот это
> {Запускаем опрос}
> For i := 0 to ATML.Count -1 do
Вот это происходит только тогда когда функция вернула пустой список и Фалсе после этого фор выполнять нет смысла
Сергей М. (2006-12-01 14:04:00) [11]
> внутри у меня
Я даже боюсь предположить, где в тебе находится это самое "внутри")
> брикпоинты не чего не показывают
>
Значит не там их расставляешь.
KyRo (2006-12-01 14:01:00) [12]
> > KyRo (01.12.06 13:02) [24]
>
>
> > Имееш в виду брек поинты ? Ими пользуюсь
>
>
> Не заметно.
Я ж говорю что весь код внутри у меня работает . То есть сам алгоритм опроса клиентов полностью функционирует и цикл проходит по всей выборке из базы и потом начинает все с начала ! А вот прервать из основного потока(А точнее не прервать потому что Тerminate выполняется ) А вызвать Thread.Free что бы освободить память не получается программа на этом зависает. При этом брикпоинты не чего не показывают
icWasya (2006-12-01 13:59:00) [13]а как вот после вот этого
if LoadATMList(ATML) =False
then
begin
ATML.Free; // <<==-- вот это
Terminate;
end;
выполняется вот это
{Запускаем опрос}
For i := 0 to ATML.Count -1 do
Сергей М. (2006-12-01 13:52:00) [14]
> sniknik © (01.12.06 13:17) [26]
> не помню какого
ComObj
Скорей всего у автора этот юнит задействован, раз он миновал засаду с исключением по этому поводу.
> KyRo (01.12.06 13:02) [24]
> Имееш в виду брек поинты ? Ими пользуюсь
Не заметно.
sniknik (2006-12-01 13:17:00) [15]> Вот только вопрос чего тогда у меня ADO работает в потоке без инициализации?
используется инициализация из основного потока в котором она делается при подключении какогото модуля (не помню какого).
Leonid Troyanovsky (2006-12-01 13:12:00) [16]
> Сергей М. © (01.12.06 12:42) [22]
> WriteToLog('ThreadId=' + IntToStr(ThreadId) + ' ' +
> e.Classname + ' ' + e.Message);
Лучше, IMHO, OutputDebugString, чтобы приучаться к
отладочным средствам, таким как, например, EventLog.
--
Regards, LVT.
KyRo (2006-12-01 13:02:00) [17]
> Вот так:
>
> procedure TMyThread.Execute;
> begin
> try
> .. все что угодно ...
> except
> on e:exception do
> WriteToLog('ThreadId=' + IntToStr(ThreadId) + ' ' +
> e.Classname + ' ' + e.Message);
> end;
> end;
> <Цитата>
Щас так и сделаю
> Я таки не понимаю, почему ты не пользуешься встроенным отладчиком
> для поиска ошибок в своем алгоритме.
Имееш в виду брек поинты ? Ими пользуюсь
KyRo (2006-12-01 12:53:00) [18]
> а почему бы Sleep не сделать?
Не подходит потому что тайм аут у меня 2 -е минуты а сообщение от клиента может прийти через 3 сек в зависимости от работы канала
> про CoInitialize(nil); все правда, не веришь твое дело.
Про CoInitialize(nil); не чего плохого не говорил !! Просто не знал про это , щас буду делать! Вот только вопрос чего тогда у меня ADO работает в потоке без инициализации ?
> именно про это и сказано, пока работает один код до другого
> не дойдет, т.е. то что ты не можеш завершить поток это и
> является "нерабочестью" про которую и сказано. и причины
> объяснены, не будеш ничего менять так и останется.
Весь код в потоке работает цикл повторяется и едет по кругу. Все статусы клиентов обновляются вот только его можно запустить а выключить не могу.
Сергей М. (2006-12-01 12:42:00) [19]
> KyRo
Я таки не понимаю, почему ты не пользуешься встроенным отладчиком для поиска ошибок в своем алгоритме.
Но даже если на это есть серьезные причины (в чем сомневаюсь) возьми себе за правило при разработке не самой тривиальной поточной логики заключать тело метода Execute в try..except, чтобы можно было протоколировать неожиданные исключения, о которых ты изначально не подозреваешь.
Вот так:
procedure TMyThread.Execute;
begin
try
.. все что угодно ...
except
on e:exception do
WriteToLog('ThreadId=' + IntToStr(ThreadId) + ' ' + e.Classname + ' ' + e.Message);
end;
end;
sniknik (2006-12-01 12:38:00) [20]> тут вы не правы все отлично работает . Не могу только завершить поток.
именно про это и сказано, пока работает один код до другого не дойдет, т.е. то что ты не можеш завершить поток это и является "нерабочестью" про которую и сказано. и причины объяснены, не будеш ничего менять так и останется.
про CoInitialize(nil); все правда, не веришь твое дело.
clickmaker © (01.12.06 12:27) [20]
> а почему бы Sleep не сделать? или через события? TEvent, WaitFor
;о)) опять же, а как оно будет работать если уже чтото выполняется и до Sleep или ожидания событий попросту не доходит дело?
тут парой изменений не обойдешься, нужно в корне чтото менять.