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

Вниз

Нужно прервать попытку соединения с БД   Найти похожие ветки 

 
AlexG ©   (2004-10-13 12:22) [0]

Использую ADO. Как мне при попытке соединения прервать этот процесс, когда он еще не дошел до таймаута. Другими словами, пользователь передумал проверять соединения и хочет его отменить, но вынужден дожидаться конца работы процесса. Это сейчас. Нужно сделать так, чтобы он не ждал, а сам отменил работу этого процесса.


 
sniknik ©   (2004-10-13 12:32) [1]

у меня аналогичная проблема... стою на остановке и уже передумал не ехать на только что ушедшем автобусе, и не хочу ждать пока следующий подойдет. как бы его вернуть?
;о))

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


 
KSergey ©   (2004-10-13 15:08) [2]

Асинхронный коннект - самое оно, по-моему


 
AlexG ©   (2004-10-13 15:22) [3]

Теперь уточнение. Мне нужно прервать до таймаута.
Сейчас у меня происходит следующее:
диалоговое окно, узер кликает на "проверить" и происходит попытка соединения с БД, но тут же он решает отменить эту проверку и закрыть диалоговое окно, он нажимет кнопку "Отмена" (вызывается метод ADOConnection.Cancel), а затем закрытия окна, но окно прячется только спустя некоторое время... А мне нужно сразу. Может лучше через потоки? А при отказе глушить поток.


 
KSergey ©   (2004-10-13 15:32) [4]

> [3] AlexG ©   (13.10.04 15:22)
> А при отказе глушить поток.

Как, интересно? Жестко?


 
AlexG ©   (2004-10-13 15:33) [5]

// Жестко?
Я не знаю как жестко глушить его. Знаю только Terminate. А есть какие-то опасности?


 
KSergey ©   (2004-10-13 15:42) [6]

Теперь почитайте про этот Terminate ;)

По секрету - нишиша он не глушит. Лишь взводит флаг, который вы же в своем коде можете проверить и добровольно завершиться (или не завершиться). Или не проверить. Или и возможности не иметь проверить (висим в попытке соединения, например). Так что просто так "красиво" прибить поток - не выйдет, увы... Ну разве что для пользователя будет полная иллюзия того, что он отказался (формочка закроется). А там глядишь - и попытка соедиения на досуге завершится...
А если пользователь и прогу захочет тут же прихлопнуть? А поток-то висит... Ну в смысле ждет.


 
AlexG ©   (2004-10-13 15:46) [7]

Да, я это прочитал... :( Вот теперь и ищу, как бы его остановить, даже "грязно"... Или какой другой способ, тоже было бы не плохо... А есть способ "убить" поток, чтобы он потом не встал?


 
KSergey ©   (2004-10-13 16:24) [8]

> [7] AlexG ©   (13.10.04 15:46)
> Да, я это прочитал... :( Вот теперь и ищу, как бы его остановить,
> даже "грязно"... Или какой другой способ, тоже было бы не
> плохо... А есть способ "убить" поток, чтобы он потом не
> встал?

Садизмом попахивает.. ;)
Можно. НО: Прохо это, очень плохо... Вся распределенная потоком память так и останется болтаться до завершения приложения...


 
malamba   (2004-10-14 10:23) [9]

>Использую ADO

ADOConnection ? Или что-то другое.
Если первое, то приведи, пжалста строку подключения.
Если она указывает на файл udl, то получается заморочка и приостановить процесс в самом нечале возможно не удасться.


 
AlexG ©   (2004-10-14 10:37) [10]

Через ADOConnection.
В ConnectionString помещаю строку, а потом ADOConnection.Connected := TRUE;


 
malamba   (2004-10-14 10:47) [11]

А сама строка подключения?

У меня, например:
FILE NAME=D:\Project\Sertifikacia\Connect.udl

Файл коннекта внешний и преравть его подключение я никак не могу.

Могу только перед ним, проверив, есть ли сетевой путь, указанный  данном файле.

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


 
AlexG ©   (2004-10-14 11:11) [12]

Я так делаю, но у меня это форма логина. Рассматриваемое соединение с БД происходит в том случае, если пользователь захотел проверить подключение к БД. Я хочу обработать тот вариант, когда пользователь нажимает эту кнопку случайно, т.е. он сразу нажимает отмену соединения. В этом случае окно логина ждет окончания соединения или вылета по таймауту, даже если я потоку говорю TerminateThread(ThreadHandle,0); , который должен его моментально вырубить... Не пойму, как моментально прервать соединение, которое еще не завершилось, и закрыть форму, в которой вызван этот поток.


 
malamba   (2004-10-14 11:19) [13]

А если плюнуть на все, подождать конца соединения, а потом, в зависимости от состояния отмены (true, false) продожать или нет?


 
KSergey ©   (2004-10-14 11:28) [14]

> [12] AlexG ©   (14.10.04 11:11)
> Я так делаю, но у меня это форма логина. Рассматриваемое
> соединение с БД происходит в том случае, если пользователь
> захотел проверить подключение к БД. Я хочу обработать тот
> вариант, когда пользователь нажимает эту кнопку случайно,
> т.е. он сразу нажимает отмену соединения.

А может в случае наличия соединения просто глушить эту кнопку - вот и все? Впрочем, а что за задача? Я мож. чего не понимаю - но где может понадобиться проверка? Т.е. програ в принципе может локально (в смысле без этого подключения) работать основную часть времени, я верно понял?


 
AlexG ©   (2004-10-14 11:32) [15]

На счет того, может она локально работать или нет, не уверен, т.к. прогу писал не я изначально, а человека, который это делал пока нет на месте. Но программа соединяется с сервером как в локальной сети, так и ч/з и-нет. При соединени проверяется имя пользователя и пароль.


 
sniknik ©   (2004-10-14 11:34) [16]

> Файл коннекта внешний и преравть его подключение я никак не могу.
разницы в подключении между udl файлом и просто строкой конекта нет, единственное до начала коннекта строка подключения считывается из файла, дальше все идет "адын в адын" ;о).

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

прервать соеденение можно только если оно будет к этому готово само, и по хелпу это вариант с асинхронным подключением. (который вы почемуто даже не обсуждаете, хотя предложение было)


 
KSergey ©   (2004-10-14 11:39) [17]

Ну а проверка - она зачем? Я к тому, что обычно если прога сама по себе работать не умеет - то проверка как таковая мне видится напрасной. Т.к. прога либо соединяется с сервером (и работает) - либо не соединяется. И не работает. Смысл проверять? Тем более - рубить "при случайном нажатии"? А руки за такое поотрывать? Нажал - сам дурак. Лично я всегда так пользователям говорю.

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

Видимо в вашей задаче проверяется возможность соединения через инет... (ну я просто не думаю, что локальная сеть столь нестабильна, что надо еще что-то проверять).

А вообще, может подход пересмотреть? Все равно поток. Ну нал юзер "проверить". Ну и долбиться в потоке до посинения. Надоело ему - "отмена". Формочка закрылась. Пользователь доволен. А поток в принципе пусть и долбится раз в 10..20..(далее по вкусу) сек. Как получилось - вывести в статус баре "УРА!". Вот только незадача: успешный тест еще не гарантирует успешного соединения по 37 причинам... А потому целесообразность просто теста мне все же не ясна до сих пор...


 
KSergey ©   (2004-10-14 11:41) [18]

> [16] sniknik ©   (14.10.04 11:34)
> прервать соеденение можно только если оно будет к этому
> готово само, и по хелпу это вариант с асинхронным подключением.

Он писал, что что-то там его не устраивает (какая-то задержка), но я лично не пользовался, ничего сказать не могу, мож. она там и вправду есть...


 
AlexG ©   (2004-10-14 11:41) [19]

Я его использую, но приложение все равно ждет конца выполнения даже операции Cancel у ADOConnection. Мне нужно, чтобы оно не ждало ничего, а сразу завершалось. Так как по моим испытаниям, время вылета потаймауту и время вылета по операции Cancel одно и то же :(


 
sniknik ©   (2004-10-14 11:52) [20]

ну во первых, какая то там задержка юзера волновать вообще не должна, ведь она в паралельном потоке происходит (насколько понял вашу ситуацию), ждать то ему ничего не надо (основной поток не тормознут).
а во вторых если
> время вылета потаймауту и время вылета по операции Cancel одно и то же
то это скорее всего значит, что коннект не асинхронный на самом деле, и Cancel попросту лишний (срабатывает только после вылета по таймауту)
хотя время для коректного завершения ему всетаки нужно, но не на полный таймаут (15 сек? в 5 дельфе, он и не меняется даже если изменить значение)
я кстати тебе советовал в другой ветке заменить дельфю и/или апдейты поставить. так вот это было не просто так. ;о)


 
AlexG ©   (2004-10-14 11:54) [21]

//KSergey ©   (14.10.04 11:39) [17]
В общем, мне было поставлено "задание". Целесообразность такую я вижу: пользователь зашел в программу, написал свои данные и нажал "Соединиться", программа начала думать. Тут он вспоминает, что данные он неправильно ввел и нужно прервать процесс соединения, исправить данные, а затем вновь попробовать соединиться. В нынешнем случае, ему придется ждать целую минуту пока завершится процесс и ему будет сказана информация, которую он и так знает. Нужно чтобы он смог прервать процесс и попытаться заного соединиться. Сейчас: пользователь ждет пока заершится ошибочный процесс, он даже может ввести свои данные после, якобы, отмены (Cancel) и отправить запрос на соединение, но все будет происходить по порядку, который длится ужасно долго: сначала завершится ошибочный процесс и только потом пойдет нормальный. Пользователь должен ждать пока все это закончится. Я хочу устранить эту задержку.


 
KSergey ©   (2004-10-14 12:12) [22]

Предлагаю такой сценарий: пользователь зашел, прога начинает (в потоке, асинхронно или как там еще) выполнять коннект. Пользоатель работает как ему вздумается. После успешного соединения - разрешаем кнопку "передать". Вот и все. Ничего лишнего пользователь не ждет.

А по поводу Cancel - что-то заинтересовало меня попробовать. А вы уверены, что коннект асинхронный?? Я вот только даже не знаю как смоделировать у себя ситуацию проблемного (вернее - длительного) коннекта...


 
AlexG ©   (2004-10-14 12:17) [23]

//sniknik
Говоришь, если одинаковое время, то не асинхронный процесс. Но я ставлю перед проверкой
dm.DB.ConnectOptions := coAsyncConnect;
Куда еще асинхроннее?


 
AlexG ©   (2004-10-14 12:23) [24]

//KSergey ©   (14.10.04 12:12) [22]
Укажи заведомо ложный сервер MSSQL или еще что-то ошибочное... Но база должна быть не на твоей машине, а всети, на каком-либо сервере.


 
AlexG ©   (2004-10-14 12:24) [25]

//KSergey ©   (14.10.04 12:12) [22]
Укажи заведомо ложный сервер MSSQL или еще что-то ошибочное... Но база должна быть не на твоей машине, а всети, на каком-либо сервере.


 
KSergey ©   (2004-10-14 12:36) [26]

А, ну да
Про ложный я что-то не сообразил ;)


 
sniknik ©   (2004-10-14 12:51) [27]

> Говоришь, если одинаковое время, то не асинхронный процесс. Но я ставлю перед проверкой
> dm.DB.ConnectOptions := coAsyncConnect;
> Куда еще асинхроннее?
я говорил основываясь не на этом а на том что у тебя всетаки ожидает окончания соедениения.

факты предоставленные суду после вынесения приговора не являются основанием для отмены этого решения (только основанием для опеляции, но это уже другое).


 
AlexG ©   (2004-10-14 13:58) [28]

Что же мне делать?


 
KSergey ©   (2004-10-14 15:44) [29]

Мдя... Ведет себя все это действительно как и рассказывал AlexG. Типа Cancel, но ждем таймаута (впрочем, пользователю-то это все не мешает творить свои делишки, надо отметить...)
Д5

Ну либо это поправлено в других версиях, либо это уж ADO такая... Либо я что-то недопонимаю...


 
AlexG ©   (2004-10-15 11:39) [30]

Я поборол проблему :) Только немного схитрил... В самом начале я пытался запихнуть коннект к БД в поток, но без Synchronize мне выдавалась ошибка, что CoInitialize не запущен. Я его пытался запустить, но результата это не давало... Но именно это и нужно было :) Порывшись дома в своей литературе, я нашел, что для многопоточности COM нужно использовать рассширенную функцию CoInitializeEx, в которой указать модель потока.  При применении CoInitializeEx(nil, COINIT_MULTITHREADED) у меня все заработало :) Теперь я могу, якобы, отменить, коннект. Конечно, поток остается в памяти и продолжает свою работу, но при правильной его работе пользователь ничего не почувствует и спокойно может закрыть диалоговое окно, которое я раньше не мог закрыть до получения таймаута.
В общем, вот так :)



Страницы: 1 вся ветка

Текущий архив: 2004.11.14;
Скачать: CL | DM;

Наверх




Память: 0.56 MB
Время: 0.054 c
1-1099382129
Геннадий
2004-11-02 10:55
2004.11.14
Out of memory


3-1098106449
Vir
2004-10-18 17:34
2004.11.14
mssql+odbc+нестандартный порт


14-1099128975
Федя
2004-10-30 13:36
2004.11.14
GTA SAN Andreas


1-1099126770
namiq
2004-10-30 12:59
2004.11.14
vid formi


1-1099416443
denis24
2004-11-02 20:27
2004.11.14
пернос итемов и listbox в мемо