Главная страница
    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.54 MB
Время: 0.036 c
1-1098867355
_Сергей_
2004-10-27 12:55
2004.11.14
Дизайнер форм


1-1098942384
CrazyHacKeRs
2004-10-28 09:46
2004.11.14
Виртуальный DataSet


14-1098814791
Rouse_
2004-10-26 22:19
2004.11.14
Саунд трек к "Бар Гадкий Койот"


1-1098893884
333and
2004-10-27 20:18
2004.11.14
Аналог функции на С++ в Delphi


1-1099036871
zorik
2004-10-29 12:01
2004.11.14
TSaveDialog FileExt





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский