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

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

Удаление TADOConnection в потоке [D7, MSSQL]


Страницы:   1 2 3

Артем ©   (2011-08-02 21:40:00) 

Здравствуйте мастера!
Проблема в том что нужно удалять соединения в потоке.

Вот примерный код потока:


type TMyThread= class(TThread);
....
FObjList: TObjectList;
Crit: TCriticalSection;
....
end;

constructor TMyThread.Create(CreateSuspended: Boolean);
begin
inherited Create(CreateSuspended);
FObjList:= TObjectList.Create(True);
Crit:= TCriticalSection.Create;
end;

procedure TMyThread.AddObject(Obj: TADOConnection);
begin
Crit.Enter;
FObjList.Add(Obj);
Crit.Leave;
end;

procedure TMyThread.Execute;
begin
while not Terminated do
 begin
  sleep(10); //чтоб поток не грузил процессор
  if FObjList.Count>0 then
   FObjList.Delete(0);
 end;
end;

//потом в основном потоке
...
var
T:TMyThread;
...
//поток создается и т.д.

...
//вызывается метод AddObject у потока
T.AddObject(Connection);


Прошелся дебагером по потоку объект вроде как уничтожается, но в ProcessExplorer'е увеливается счетик User Handles ровно на количество созданных мной соединений. CoInitialize и CoUninitialize никак не помогают.
Соединения надо удалять так, потому что сединение с СУБД MsSQL может не пройти по каким-либо причинам, и соединение подвисает, а при уничтожении соединения и основной поток, поэтому уничтожение убрано в отдельный поток.

Помогите кто-нибудь, кто сталкивался с подобным.


DiamondShark   (2011-08-03 12:32:00) [21]


> У меня был вопрос почему после уничтожения коннекта остаются
> User Handles.

А что такое, по-твоему, User Handles?
Ну, вот, например, подсистема СОМ создаёт невидимые окна для обслуживания маршалинга. Окно -- это один из типов User Handle. Оно тебя сильно волнует?


DiamondShark   (2011-08-03 12:27:00) [22]


> sniknik ©   (03.08.11 11:56) [19]
> > CommandTimeOut и ConnectionTimeout не срабатывают????
> у тебя, что пятая дельфя?

При чём здесь пятая дельфя? Он говорит про случай физической недоступности компьютеров. Здесь ни при чём не только дельфя, но и ни АДО ни МССКЛ дбпровайдер, ни дблиб. Это фича сокетов. Ну нету никакой возможности прервать сокетный connect(), ждущий ответа от недоступного хоста. Нету, хоть ты тресни.

Инфа 100%, что при недоступности хоста ConnectionTimeout курит в углу, а управление возвращается, когда TCP-стек соблаговолит. Так себя ведёт и АДО с МССКЛ дбпровайдером, и ОДБЦ драйвер, дотНЕТ-клиент.
А всё, сцуко, потому, что все они, в конце-концов, вызывают синхронный сокетный connect().


Артем   (2011-08-03 12:25:00) [23]


> > CommandTimeOut и ConnectionTimeout не срабатывают
> ???? у тебя, что пятая дельфя? только там, да и то без обновлений,
>  была проблема с таймаутами. хотя, решаемая, правда через
> генофонд.


Пробовал в седьмой дельфи и XE, все равно не срабатывает таймаут.


> > В этом другом потоке коннект и должен уничтожаться.
> он там, или оттуда у тебя и уничтожается, но таймаут от
> операции все одно останется на операции, и с этим ничего
> в синхронном режиме не поделать.

Если я отправил коннект на уничтожение, то мне уже без разницы что он подвис.


> > Есть функция .... бла.бла.бла.
> меньше слов больше дел.. кода!

Зачем тебе код этой функции?
У меня был вопрос почему после уничтожения коннекта остаются User Handles.


sniknik   (2011-08-03 11:56:00) [24]

> CommandTimeOut и ConnectionTimeout не срабатывают
???? у тебя, что пятая дельфя? только там, да и то без обновлений, была проблема с таймаутами. хотя, решаемая, правда через генофонд.

> В этом другом потоке коннект и должен уничтожаться.
он там, или оттуда у тебя и уничтожается, но таймаут от операции все одно останется на операции, и с этим ничего в синхронном режиме не поделать.

> Есть функция .... бла.бла.бла.
меньше слов больше дел.. кода!


Артем   (2011-08-03 10:02:00) [25]

Есть функция, которая делает соединение с помощью дополнительного потока.
В функцию передаются ссылка на коннект и таймаут.
Функция создает поток, передает в поток коннект. Потом в цикле проверяет значение флажка в потоке, и если в течение времени таймаута не флажек False, то поток убивается, функция возвращает False. Или True если флажек стал True до истечения таймаута.

Если функция возвращает false, то он передается в другой поток на уничтожение, чтобы основной поток не задерживать своими таймаутами. В этом другом потоке коннект и должен уничтожаться.


Anatoly Podgoretsky   (2011-08-03 09:53:00) [26]

> Артем  (03.08.2011 09:45:16)  [16]

> А ждать пока пройдут все таймуаты нельзя.

Тогда откуда ты решил, что соединение не проходит?


Артем   (2011-08-03 09:45:00) [27]


> кстати а что вообще за бредовая идея уничтожать коннект
> в процессе работы? ели он постоянно нужен. а если не нужен.
> .. ну пусть себе "повисит" дополнительный поток, не связанный
> с основным... чем он мешает то?


Если соединение не проходит (коннект завис или еще что-то), то его надо уничтожить. А ждать пока пройдут все таймуаты нельзя. CommandTimeOut и ConnectionTimeout не срабатывают если нет физического соединения с компьютером, на котором работает MSSQL Server (просто к сети не подключен или вообще выключен), в остальных они срабатывают.


sniknik   (2011-08-03 09:33:00) [28]

> пасть
пусть

кстати а что вообще за бредовая идея уничтожать коннект в процессе работы? ели он постоянно нужен. а если не нужен... ну пусть себе "повисит" дополнительный поток, не связанный с основным... чем он мешает то?


sniknik   (2011-08-03 09:30:00) [29]

> Как уничтожить соединение чтобы основной поток не завис (или если вынести в отдельный поток работу с БД чтобы этот поток не зависал)?
сделать все независимым от основного, "от а до я", и в этом случае совершенно неважно, что какой то из потоков "завис".
> она вообще должна идти фоново.
о!!!
> А подвисание потока, в котором выполняются запросы, недопустимо.
с чего это если используется синхронный режим (совет про асинхронный ты проигнорировал) и есть вполне уместный таймаут (это не зависание) от обязательного завершения операции (дать ответ).

> уничтожался бы в другом, чтобы основной не подвисал в случае отсутствия связи.
"висит" (тут это неправильное слово) не уничтожение, а ожидание выполняемой операции, пасть даже результатом таймаут, а операция у тебя выполняется где?...


Артем   (2011-08-03 08:47:00) [30]

Работа с БД не связана с пользовательским интерфейсом, она вообще должна идти фоново. А подвисание потока, в котором выполняются запросы, недопустимо. Например, если нет соединения с СУБД, но есть с самим компьютером то подвиснет ненадолго (на время таймаута, заданного в adoconnection'е), или если нет связи с компьютером, то зависнут может надолго (у меня было и по 2-3 минуты). Для работы программы даже подвисания на 10 сек. недопустимы.

Вот я и хочу, чтобы в основном потоке выполнялось соединение, выполнялись запросы, а сам adoconnection уничтожался бы в другом, чтобы основной не подвисал в случае отсутствия связи.


Вариант   (2011-08-03 08:32:00) [31]


> Артем   (03.08.11 08:02) [9]


> Мной сделано

В таком варианте не поможет.

>  Как его лучше уничтожить, чтобы не завис поток?

Если речь про основной поток, то например создавать, работать и уничтожать соединение и/или другие ADO компоненты в одном дополнительном потоке. Кстати тогда возможно все ограничится TADOCommand для доп. потока. Пусть висит доп. поток. Отвиснет, возникнет ошибка - передашь ее в основной поток. И еще в этом случае придется решать проблемы корректной передачи результатов запроса из одного потока в другой. Или смириться тем, что при ошибках в соединении возможно подвисание пользовательского интерфейса, но работать в основном потоке и не иметь других проблем.  Тут тебе видней.


Артем   (2011-08-03 08:14:00) [32]


> p.s. если ты уверен, что все правильно, и все отвергаешь,
>  то тебе не сюда, тебе в микрософт писать нужно... вот,
> что за фигня, написали операционку не совместимую с твоей
> программой...


Я сюда и написал, потому что не уверен что правильно сделал.
В общем, мне надо чтобы так было:
Основной поток, например по таймеру, соединяется с БД, выполняет запросы и т.д. (при соединении поток не зависнет, даже если нет физического соединения с сервером, но зависнет при уничтожении).
Как уничтожить соединение чтобы основной поток не завис (или если вынести в отдельный поток работу с БД чтобы этот поток не зависал)?


sniknik   (2011-08-03 08:03:00) [33]

> У него же TObjectList, а не TList
;( не обратил внимания.

> так это, продемонстрируете мастер-код? а ту поржут... а?
писать просто так? абстрактный код? ... даже попытка достойна ржача.
- "когда у общества нет цветовой дифференциации штанов, то нет цели! А когда нет цели…" © Кин-Дза-Дза
в смысле, код должен иметь цель, а код без цели лишен смысла...

> Поток в котором создается TADOConnection не подвиснет (сделано так чтоб не подвисал)
> CoInitialize и CoUninitialize никак не помогают.
они рассчитаны на  поток, и обязательны для каждого потока, т.е. сначала инициализируется COM модель, после в нем создается COM объект. а у тебя, "твоя модель" совсем не работает, т.к. "завязки" у обьекта на другой поток.

p.s. если ты уверен, что все правильно, и все отвергаешь, то тебе не сюда, тебе в микрософт писать нужно... вот, что за фигня, написали операционку не совместимую с твоей программой...


Артем   (2011-08-03 08:02:00) [34]

Мной сделано. Главное что поток не подвиснет при подключении/отключении.
Но подвиснет при уничтожении соединения. Как его лучше уничтожить, чтобы не завис поток?


Вариант   (2011-08-03 07:49:00) [35]


> Артем   (03.08.11 07:34) [7]

Кем сделано? Почитай про COM объекты , апартаменты....


Артем   (2011-08-03 07:34:00) [36]


> > Артем   (02.08.11 21:40)
> >
> > Соединения надо удалять так, потому что сединение с СУБД
> > MsSQL может не пройти по каким-либо причинам, и соединение
> > подвисает, а при уничтожении соединения и основной поток,
>
> >  поэтому уничтожение убрано в отдельный поток.
>
> Реализация работы с потоком сделана неверно. Критическая
> секция ничего не защищает, да и сам поток не нужен ибо -
> >
> "Кто к нам с мечом придет, тот от меча и погибнет" (С) к/ф
> "Александр Невский" -расшифрую,  тот поток, в котором был
> создан TADOConnection  будет "висеть" в любом случае, если
> зависнет TADOConnection, в каком бы ты потоке его не закрывал(освобождал).
>


Поток в котором создается TADOConnection не подвиснет (сделано так чтоб не подвисал)


Вариант   (2011-08-03 07:24:00) [37]


> Артем   (02.08.11 21:40)
>
> Соединения надо удалять так, потому что сединение с СУБД
> MsSQL может не пройти по каким-либо причинам, и соединение
> подвисает, а при уничтожении соединения и основной поток,
>  поэтому уничтожение убрано в отдельный поток.

Реализация работы с потоком сделана неверно. Критическая секция ничего не защищает, да и сам поток не нужен ибо ->
"Кто к нам с мечом придет, тот от меча и погибнет" (С) к/ф "Александр Невский" -расшифрую,  тот поток, в котором был создан TADOConnection  будет "висеть" в любом случае, если зависнет TADOConnection, в каком бы ты потоке его не закрывал(освобождал).


Артем   (2011-08-03 05:38:00) [38]

TObjectLIst сам освобождает память при удалении объекта из списка.


Игорь Шевченко   (2011-08-03 00:10:00) [39]

http://www.gunsmoker.ru/2008/10/x-y-z.html


знайка   (2011-08-02 23:49:00) [40]


> Хотя в целом - безусловно говнокод
так это, продемонстрируете мастер-код? а ту поржут... а?


Страницы:   1 2 3

Наверх

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