![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Нужно прервать попытку соединения с БД [D5, MSSQL]
AlexG © (2004-10-13 12:22:00)Использую ADO. Как мне при попытке соединения прервать этот процесс, когда он еще не дошел до таймаута. Другими словами, пользователь передумал проверять соединения и хочет его отменить, но вынужден дожидаться конца работы процесса. Это сейчас. Нужно сделать так, чтобы он не ждал, а сам отменил работу этого процесса.
AlexG (2004-10-15 11:39:00) [1]Я поборол проблему :) Только немного схитрил... В самом начале я пытался запихнуть коннект к БД в поток, но без Synchronize мне выдавалась ошибка, что CoInitialize не запущен. Я его пытался запустить, но результата это не давало... Но именно это и нужно было :) Порывшись дома в своей литературе, я нашел, что для многопоточности COM нужно использовать рассширенную функцию CoInitializeEx, в которой указать модель потока. При применении CoInitializeEx(nil, COINIT_MULTITHREADED) у меня все заработало :) Теперь я могу, якобы, отменить, коннект. Конечно, поток остается в памяти и продолжает свою работу, но при правильной его работе пользователь ничего не почувствует и спокойно может закрыть диалоговое окно, которое я раньше не мог закрыть до получения таймаута.
В общем, вот так :)
KSergey (2004-10-14 15:44:00) [2]Мдя... Ведет себя все это действительно как и рассказывал AlexG. Типа Cancel, но ждем таймаута (впрочем, пользователю-то это все не мешает творить свои делишки, надо отметить...)
Д5
Ну либо это поправлено в других версиях, либо это уж ADO такая... Либо я что-то недопонимаю...
AlexG (2004-10-14 13:58:00) [3]Что же мне делать?
sniknik (2004-10-14 12:51:00) [4]> Говоришь, если одинаковое время, то не асинхронный процесс. Но я ставлю перед проверкой
> dm.DB.ConnectOptions := coAsyncConnect;
> Куда еще асинхроннее?
я говорил основываясь не на этом а на том что у тебя всетаки ожидает окончания соедениения.
факты предоставленные суду после вынесения приговора не являются основанием для отмены этого решения (только основанием для опеляции, но это уже другое).
KSergey (2004-10-14 12:36:00) [5]А, ну да
Про ложный я что-то не сообразил ;)
AlexG (2004-10-14 12:24:00) [6]//KSergey © (14.10.04 12:12) [22]
Укажи заведомо ложный сервер MSSQL или еще что-то ошибочное... Но база должна быть не на твоей машине, а всети, на каком-либо сервере.
AlexG (2004-10-14 12:23:00) [7]//KSergey © (14.10.04 12:12) [22]
Укажи заведомо ложный сервер MSSQL или еще что-то ошибочное... Но база должна быть не на твоей машине, а всети, на каком-либо сервере.
AlexG (2004-10-14 12:17:00) [8]//sniknik
Говоришь, если одинаковое время, то не асинхронный процесс. Но я ставлю перед проверкой
dm.DB.ConnectOptions := coAsyncConnect;
Куда еще асинхроннее?
KSergey (2004-10-14 12:12:00) [9]Предлагаю такой сценарий: пользователь зашел, прога начинает (в потоке, асинхронно или как там еще) выполнять коннект. Пользоатель работает как ему вздумается. После успешного соединения - разрешаем кнопку "передать". Вот и все. Ничего лишнего пользователь не ждет.
А по поводу Cancel - что-то заинтересовало меня попробовать. А вы уверены, что коннект асинхронный?? Я вот только даже не знаю как смоделировать у себя ситуацию проблемного (вернее - длительного) коннекта...
AlexG (2004-10-14 11:54:00) [10]//KSergey © (14.10.04 11:39) [17]
В общем, мне было поставлено "задание". Целесообразность такую я вижу: пользователь зашел в программу, написал свои данные и нажал "Соединиться", программа начала думать. Тут он вспоминает, что данные он неправильно ввел и нужно прервать процесс соединения, исправить данные, а затем вновь попробовать соединиться. В нынешнем случае, ему придется ждать целую минуту пока завершится процесс и ему будет сказана информация, которую он и так знает. Нужночтобы он смог прервать процесс и попытаться заного соединиться. Сейчас: пользователь ждет пока заершится ошибочный процесс, он даже может ввести свои данные после, якобы, отмены (Cancel) и отправить запрос на соединение, но все будет происходить по порядку, который длится ужасно долго: сначала завершится ошибочный процесс и только потом пойдет нормальный. Пользователь должен ждать пока все это закончится. Я хочу устранить эту задержку.
sniknik (2004-10-14 11:52:00) [11]ну во первых, какая то там задержка юзера волновать вообще не должна, ведь она в паралельном потоке происходит (насколько понял вашу ситуацию), ждать то ему ничего не надо (основной поток не тормознут).
а во вторых если
> время вылета потаймауту и время вылета по операции Cancel одно и то же
то это скорее всего значит, что коннект не асинхронный на самом деле, и Cancel попросту лишний (срабатывает только после вылета по таймауту)
хотя время для коректного завершения ему всетаки нужно, но не на полный таймаут (15 сек? в 5 дельфе, он и не меняется даже если изменить значение)
я кстати тебе советовал в другой ветке заменить дельфю и/или апдейты поставить. так вот это было не просто так. ;о)
AlexG (2004-10-14 11:41:00) [12]Я его использую, но приложение все равно ждет конца выполнения даже операции Cancel у ADOConnection. Мне нужно, чтобы оно не ждало ничего, а сразу завершалось. Так как по моим испытаниям, время вылета потаймауту и время вылета по операции Cancel одно и то же :(
KSergey (2004-10-14 11:41:00) [13]> [16] sniknik © (14.10.04 11:34)
> прервать соеденение можно только если оно будет к этому
> готово само, и по хелпу это вариант с асинхронным подключением.
Он писал, что что-то там его не устраивает (какая-то задержка), но я лично не пользовался, ничего сказать не могу, мож. она там и вправду есть...
KSergey (2004-10-14 11:39:00) [14]Ну а проверка - она зачем? Я к тому, что обычно если прога сама по себе работать не умеет - то проверка как таковая мне видится напрасной. Т.к. прога либо соединяется с сервером (и работает) - либо не соединяется. И не работает. Смысл проверять? Тем более - рубить "при случайном нажатии"? А руки за такое поотрывать? Нажал - сам дурак. Лично я всегда так пользователям говорю.
Другое дело, что есть смысл сделать так, чтобы возможности нажать куда не след. у них не было - это другой разговор.
Видимо в вашей задаче проверяется возможность соединения через инет... (ну я просто не думаю, что локальная сеть столь нестабильна, что надо еще что-то проверять).
А вообще, может подход пересмотреть? Все равно поток. Ну нал юзер "проверить". Ну и долбиться в потоке до посинения. Надоело ему - "отмена". Формочка закрылась. Пользователь доволен. А поток в принципе пусть и долбится раз в 10..20..(далее по вкусу) сек. Как получилось - вывести в статус баре "УРА!". Вот только незадача: успешный тест еще не гарантирует успешного соединения по 37 причинам... А потому целесообразность просто теста мне все же не ясна до сих пор...
sniknik (2004-10-14 11:34:00) [15]> Файл коннекта внешний и преравть его подключение я никак не могу.
разницы в подключении между udl файлом и просто строкой конекта нет, единственное до начала коннекта строка подключения считывается из файла, дальше все идет "адын в адын" ;о).
люди! не обманывайте сами себя, вы же не конект завершаете, вы пытаетесь убить поток в котором он определен, а т.к. тот сам по себе является потоком (а может и не одним), то завершится он обязан даже если его родителя "убили", ведь убили его варварским способом он никуда никаких сообщений послать не может и "детей" по факту собственного "убийства" тоже не "убивает". а при "цивилизованном" завершении он уже сам ожидает конца процесса.
прервать соеденение можно только если оно будет к этому готово само, и по хелпу это вариант с асинхронным подключением. (который вы почемуто даже не обсуждаете, хотя предложение было)
AlexG (2004-10-14 11:32:00) [16]На счет того, может она локально работать или нет, не уверен, т.к. прогу писал не я изначально, а человека, который это делал пока нет на месте. Но программа соединяется с сервером как в локальной сети, так и ч/з и-нет. При соединени проверяется имя пользователя и пароль.
KSergey (2004-10-14 11:28:00) [17]> [12] AlexG © (14.10.04 11:11)
> Я так делаю, но у меня это форма логина. Рассматриваемое
> соединение с БД происходит в том случае, если пользователь
> захотел проверить подключение к БД. Я хочу обработать тот
> вариант, когда пользователь нажимает эту кнопку случайно,
> т.е. он сразу нажимает отмену соединения.
А может в случае наличия соединения просто глушить эту кнопку - вот и все? Впрочем, а что за задача? Я мож. чего не понимаю - но где может понадобиться проверка? Т.е. програ в принципе может локально (в смысле без этого подключения) работать основную часть времени, я верно понял?
malamba (2004-10-14 11:19:00) [18]А если плюнуть на все, подождать конца соединения, а потом, в зависимости от состояния отмены (true, false) продожать или нет?
AlexG (2004-10-14 11:11:00) [19]Я так делаю, но у меня это форма логина. Рассматриваемое соединение с БД происходит в том случае, если пользователь захотел проверить подключение к БД. Я хочу обработать тот вариант, когда пользователь нажимает эту кнопку случайно, т.е. он сразу нажимает отмену соединения. В этом случае окно логина ждет окончания соединения или вылета по таймауту, даже если я потоку говорю TerminateThread(ThreadHandle,0); , который должен его моментально вырубить... Не пойму, как моментально прервать соединение, которое еще не завершилось, и закрыть форму, в которой вызван этот поток.
malamba (2004-10-14 10:47:00) [20]А сама строка подключения?
У меня, например:
FILE NAME=D:\Project\Sertifikacia\Connect.udl
Файл коннекта внешний и преравть его подключение я никак не могу.
Могу только перед ним, проверив, есть ли сетевой путь, указанный данном файле.
Вообще-то, подключение идет у меня в потоке, а в основном приложении запускается таймер - если прошло больше 15 сек, то поток он закрывает.