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

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

Про Indy и синхронизацию потоков [D6, WinXP]


Страницы:   1 2

NorthMan ©   (2005-07-01 08:07:00) 

Народ, подскажите, как лучше сделать.
Проблема такая:
Есть idTCPServer. В OnExecute принимается запрос от клиента, затем нужно выполнить внешнюю процедуру типа TForm1.GetData, в которой выполняется запрос в базу через ADO (выполняется AThread.Synchronize(TForm1.GetData)), а результат запроса необходимо вернуть в OnExecute. Подскажите, как с т.з. потока правильнее передать результат запроса. Через глобальную переменную, как мне кажется, нельзя, т.к. клиентов в каждый момент времени может быть много.


NorthMan   (2005-07-06 14:19:00) [1]

Все заработало, спасибо!


Reindeer Moss Eater   (2005-07-04 14:28:00) [2]

Погоди, что-то я запарился. Идея вот какая:
Создаем пустое приложение  типа Service Application. Добавляем в него DataModule. На DM помещаем таймер, Connection и Query.


В момент коннекта очередного клиента создать новый экземпляр этого модуля данных. Ссылку на него сохранить в присоединившемся клиенте.
При обработке запросов клиента работать с экземпляром модуля данных этого клиента.
Когда клиент сделал дисконнект, убивать его модуль данных.


Slym   (2005-07-04 10:01:00) [3]

Ты 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;


NorthMan   (2005-07-01 16:11:00) [4]

хорошо, учту совет, спасибо!


Digitman   (2005-07-01 15:57:00) [5]

но я так и не понял, зачем нужен таймер ...

выборку же можно (и нужно !) делать по запросу клиента, а если клиент "молчит" (подключился и ничего не "просит"), то зачем же вхолостую молотить ?


Digitman   (2005-07-01 15:53:00) [6]

ты отладь взаимодействие IdTCPServer'а и ADO в обычном приложении !

а уж потом ты этот отлаженный алгоритм легко перенесешь в сервис и тогда уже будешь думать о проблемах доступа к АДО в сервисе под системной уч.записью ..

перенести ведь несложно - создаешь/активируешь IdTCPServer в OnServiceStart, деактивируешь/уничтожаешь в OnServiceStop ...


NorthMan   (2005-07-01 15:45:00) [7]

все так, только эта служба должна работать на контроллере домена. Соответственно, интерфейс не нужен и должна работать под системной учетной записью.


Digitman   (2005-07-01 15:35:00) [8]


> Сервис будет обслуживать запросы клиентов


разве обычное приложение, использующее те же самые TCPServer/TCPClient, не в состоянии точно так же обслуживать те же самые запросы ?


NorthMan   (2005-07-01 15:30:00) [9]

Сервис будет обслуживать запросы клиентов (использую Indy TCPServer/TCPClient), но до этого еще надо разобраться, почему из службы не удается прочитать таблицы. По-прежнему вываливает исключение "OLE error 80030002".


Digitman   (2005-07-01 15:09:00) [10]


> NorthMan   (01.07.05 14:44) [21]



> Создаем пустое приложение  типа Service Application


при описанной тобой логике я не вижу никакого резона реализации ее именно в сервис-приложении

объясни, зачем тебе понадобилось именно сервис-приложение ?
нем не устраивает обычное ?


NorthMan   (2005-07-01 14:44:00) [11]

Погоди, что-то я запарился. Идея вот какая:
Создаем пустое приложение  типа Service Application. Добавляем в него DataModule. На DM помещаем таймер, Connection и Query. По таймеру выполняем приведенный выше код. Больше никаких действий не производится. Пусть в качестве глобальной переменной будет количество записей в Query. Беда в том, что Query не открывается, а вываливает исключение.


Digitman   (2005-07-01 14:31:00) [12]


> чтобы выборка производилась периодически, и заполнялись
> некоторые глобальные переменные


и что далее происходит с выборкой и этими глоб.переменными ?

ЧЕМ собственно поток сервиса (не путать с основным потоком сервис-процесса !) все это время (с момента старта до момента останова сервиса) у тебя занят ?


NorthMan   (2005-07-01 14:25:00) [13]

а зачем он вообще нужен ?

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

с каким исключением ?

Access violation at address 0048BD98 in module 'Server.exe'. Read of address 00000178


Digitman   (2005-07-01 14:20:00) [14]

т.е. и таймер лежит там же, на DataModule1 ?

а зачем он вообще нужен ?

и зачем в основном потоке нужны явные CoInitialize/CoUninitialize , если они и так уже неявно выполняются в ходе иниц-ции/деиниц-ции модуля ActiveX ?


> тут вываливается


с каким исключением ?


NorthMan   (2005-07-01 14:06:00) [15]

DataModule1 создается в основном потоке

AdoConnection, GetInfoQuery - это компоненты, которые ты "бросил" на DataModule1 в дизайн-тайм ?

Да


Digitman   (2005-07-01 13:52:00) [16]


> NorthMan   (01.07.05 13:49) [14]


в каком потоке создается DataModule1 ?

AdoConnection, GetInfoQuery - это компоненты, которые ты "бросил" на DataModule1 в дизайн-тайм ?


NorthMan   (2005-07-01 13:50:00) [17]

А SP2 XP-шный не может всю малину портить?


NorthMan   (2005-07-01 13:49:00) [18]

Вот код:
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:41:00) [19]

ага, понял, это не при CoInitialize(nil) происходит, а при AdoConnection.Open


Digitman   (2005-07-01 13:39:00) [20]


> NorthMan   (01.07.05 13:31) [11]


приводи код


Страницы:   1 2

Наверх

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