Форум: "Сети";
Текущий архив: 2005.10.23;
Скачать: [xml.tar.bz2];
ВнизПро Indy и синхронизацию потоков Найти похожие ветки
← →
NorthMan (2005-07-01 08:07) [0]Народ, подскажите, как лучше сделать.
Проблема такая:
Есть idTCPServer. В OnExecute принимается запрос от клиента, затем нужно выполнить внешнюю процедуру типа TForm1.GetData, в которой выполняется запрос в базу через ADO (выполняется AThread.Synchronize(TForm1.GetData)), а результат запроса необходимо вернуть в OnExecute. Подскажите, как с т.з. потока правильнее передать результат запроса. Через глобальную переменную, как мне кажется, нельзя, т.к. клиентов в каждый момент времени может быть много.
← →
Slym © (2005-07-01 08:26) [1]Ну и делалбы в каждом потоке свой запрос... указывая общий Конекшн
И никаких синхронизаций и подвисов всех клиентов из-за того что один запрос подвис.
← →
NorthMan (2005-07-01 11:40) [2]беда в том, что сервер организован в виде службы, а ADO что-то не очень любит такие выкрутасы
← →
Digitman © (2005-07-01 11:43) [3]
> сервер организован в виде службы, а ADO что-то не очень
> любит такие выкрутасы
что, прямо так и говорит, мол, не люблю и все тут ?
а при чем здесь тогда синхронизация ?
← →
Slym © (2005-07-01 11:59) [4]Четы по ADO в сервисе... Ты пробовал? Я да.
У меня веб сервер (на Indy) как сервис пишет логи в Access через ADO, динамические страницы берут данные из таблиц в разных ДБ тоже через ADO (добавление тоже имеется с транзакциями иногда), + небольшое клиент-сервер приложение обслуживает на ура
← →
Slym © (2005-07-01 12:07) [5]Нагрузка на сервер 1000-10000 постов в день
перфоманс каунтеры показывают 10-20 мс на запрос выборки
30-500 мс на запросы вставки
И не вылетает (тьфу, тьфу, тьфу)
← →
NorthMan (2005-07-01 12:13) [6]2 Slym
Рад, что все так круто, но проблема есть и ее хотелось бы решить. Поясните, как лучше: динамически создавать экземпляр TAdoQuery или можно юзать компоненты, бросив их, например, на TDataModule? И как это все согласовать с потоками Indy
← →
Digitman © (2005-07-01 12:54) [7]
> динамически создавать экземпляр TAdoQuery или можно юзать
> компоненты, бросив их, например, на TDataModule?
без разницы
> как это все согласовать с потоками Indy
Indy-потоки ничем не отличаются от любых иных наследников TThread
← →
NorthMan (2005-07-01 13:06) [8]Спасибо, вроде начинаю разбираться. Вот только еще такая проблема возникает: когда пытаюсь делать AdoQuery.Open выдается ошибка OLE error 80030002. Инфы по этому поводу не много. Понял, что найти чего-то не может, но что конкретно? Путь к базе прописан, в DesignTime все открывается.
← →
Digitman © (2005-07-01 13:09) [9]CoInitialize/CoUninitialize выполняешь ?
← →
Slym © (2005-07-01 13:29) [10]TAdoQuery я бы создавал динамически в теле потока.
CoInitialize Нужно вызывать в главном потоке сервиса как минимум до подключения к ДБ обычно на OnServiceStart и в перед созданием/подключением TAdoQuery в дочерних потоках, ну и соответственно CoUninitialize вконце
← →
NorthMan (2005-07-01 13:31) [11]Выполняю, но при CoInitialize(nil); получаю Access violation.... Что за фигня?
← →
Digitman © (2005-07-01 13:39) [12]
> NorthMan (01.07.05 13:31) [11]
приводи код
← →
NorthMan (2005-07-01 13:41) [13]ага, понял, это не при CoInitialize(nil) происходит, а при AdoConnection.Open
← →
NorthMan (2005-07-01 13:49) [14]Вот код:
procedure TDataModule1.RefreshTimerTimer(Sender: TObject);
var
r_count: integer;
begin
try
r_count := 0;
CoInitialize(nil);
AdoConnection.Open; //<-- тут вываливается
GetInfoQuery.Open;
r_count := GetInfoQuery.RecordCount;
if r_count > 0 then
begin
GetInfoQuery.First;
...
finally
GetInfoQuery.Close;
AdoConnection.Close;
CoUninitialize;
end;
end;
← →
NorthMan (2005-07-01 13:50) [15]А SP2 XP-шный не может всю малину портить?
← →
Digitman © (2005-07-01 13:52) [16]
> NorthMan (01.07.05 13:49) [14]
в каком потоке создается DataModule1 ?
AdoConnection, GetInfoQuery - это компоненты, которые ты "бросил" на DataModule1 в дизайн-тайм ?
← →
NorthMan (2005-07-01 14:06) [17]DataModule1 создается в основном потоке
AdoConnection, GetInfoQuery - это компоненты, которые ты "бросил" на DataModule1 в дизайн-тайм ?
Да
← →
Digitman © (2005-07-01 14:20) [18]т.е. и таймер лежит там же, на DataModule1 ?
а зачем он вообще нужен ?
и зачем в основном потоке нужны явные CoInitialize/CoUninitialize , если они и так уже неявно выполняются в ходе иниц-ции/деиниц-ции модуля ActiveX ?
> тут вываливается
с каким исключением ?
← →
NorthMan (2005-07-01 14:25) [19]а зачем он вообще нужен ?
Таймер лежит на DataModule1 и нужен для того, чтобы выборка производилась периодически, и заполнялись некоторые глобальные переменные.
с каким исключением ?
Access violation at address 0048BD98 in module "Server.exe". Read of address 00000178
← →
Digitman © (2005-07-01 14:31) [20]
> чтобы выборка производилась периодически, и заполнялись
> некоторые глобальные переменные
и что далее происходит с выборкой и этими глоб.переменными ?
ЧЕМ собственно поток сервиса (не путать с основным потоком сервис-процесса !) все это время (с момента старта до момента останова сервиса) у тебя занят ?
← →
NorthMan (2005-07-01 14:44) [21]Погоди, что-то я запарился. Идея вот какая:
Создаем пустое приложение типа Service Application. Добавляем в него DataModule. На DM помещаем таймер, Connection и Query. По таймеру выполняем приведенный выше код. Больше никаких действий не производится. Пусть в качестве глобальной переменной будет количество записей в Query. Беда в том, что Query не открывается, а вываливает исключение.
← →
Digitman © (2005-07-01 15:09) [22]
> NorthMan (01.07.05 14:44) [21]
> Создаем пустое приложение типа Service Application
при описанной тобой логике я не вижу никакого резона реализации ее именно в сервис-приложении
объясни, зачем тебе понадобилось именно сервис-приложение ?
нем не устраивает обычное ?
← →
NorthMan (2005-07-01 15:30) [23]Сервис будет обслуживать запросы клиентов (использую Indy TCPServer/TCPClient), но до этого еще надо разобраться, почему из службы не удается прочитать таблицы. По-прежнему вываливает исключение "OLE error 80030002".
← →
Digitman © (2005-07-01 15:35) [24]
> Сервис будет обслуживать запросы клиентов
разве обычное приложение, использующее те же самые TCPServer/TCPClient, не в состоянии точно так же обслуживать те же самые запросы ?
← →
NorthMan (2005-07-01 15:45) [25]все так, только эта служба должна работать на контроллере домена. Соответственно, интерфейс не нужен и должна работать под системной учетной записью.
← →
Digitman © (2005-07-01 15:53) [26]ты отладь взаимодействие IdTCPServer"а и ADO в обычном приложении !
а уж потом ты этот отлаженный алгоритм легко перенесешь в сервис и тогда уже будешь думать о проблемах доступа к АДО в сервисе под системной уч.записью ..
перенести ведь несложно - создаешь/активируешь IdTCPServer в OnServiceStart, деактивируешь/уничтожаешь в OnServiceStop ...
← →
Digitman © (2005-07-01 15:57) [27]но я так и не понял, зачем нужен таймер ...
выборку же можно (и нужно !) делать по запросу клиента, а если клиент "молчит" (подключился и ничего не "просит"), то зачем же вхолостую молотить ?
← →
NorthMan (2005-07-01 16:11) [28]хорошо, учту совет, спасибо!
← →
Slym © (2005-07-04 10:01) [29]Ты AdoConnection.Free нигде не делаешЪ?
Зачем AdoConnection постоянно открывать/закрывать?
Тело потока:
begin
CoInitialize(nil);
try
GetInfoQuery:=TADOQuery.Create(nil);
try
GetInfoQuery.Connection:=AdoConnection;
GetInfoQuery.LockType:=ltReadOnly;
GetInfoQuery.Open;
while not GetInfoQuery.EOF do
begin
...
GetInfoQuery.Next;
end;
finally
GetInfoQuery.Free;
end;
finally
CoUninitialize;
end;
{псевдокод}Socket.WriteResult(MyResult);
end;
← →
Reindeer Moss Eater © (2005-07-04 14:28) [30]Погоди, что-то я запарился. Идея вот какая:
Создаем пустое приложение типа Service Application. Добавляем в него DataModule. На DM помещаем таймер, Connection и Query.
В момент коннекта очередного клиента создать новый экземпляр этого модуля данных. Ссылку на него сохранить в присоединившемся клиенте.
При обработке запросов клиента работать с экземпляром модуля данных этого клиента.
Когда клиент сделал дисконнект, убивать его модуль данных.
← →
NorthMan (2005-07-06 14:19) [31]Все заработало, спасибо!
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2005.10.23;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.039 c