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

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

Компоненты ADO в сервисе Win32 [D6, IB6.x, MSSQL]


Страницы:   1 2 3

iZEN ©   (2002-11-15 15:23:00) 

Компоненты ADO в консольном приложении. :[
Возможно ли такое в принципе?

Пробую создать сервисное приложение под Windows2000/XP, где в run-time инстанцируются компоненты TADOConnection и TADOQuery.
Создаются нити на основе TThread, в которые передаются экземпляры этих компонентов и они начинают работу (должны начать - в оконном тестовом приложении всё работает).

...
{$APPTYPE CONSOLE}

uses
ActiveX,...;
...
var
Connection: TADOConnection;
Query: TADOQuery;
Writer: TWriterTask;//Дочерняя нить
...
procedure TConverter.ServiceStart(Sender: TService; var Started: Boolean);
begin
OLEInitialize(nil);
Connection := TADOConnection.Create(nil);
Query := TADOQuery.Create(nil);
Query.Connection := Connection;
Writer := TWriterTask.Create();
Writer.FreeOnTerminate := True;
Writer.SetConnection(Connection);
...
//---Стартуем нить
Writer.Resume();
end;

procedure TConverter.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
//Очистка и завершение работы сервиса
...
OLEUninitialize();
end.

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

Как это побороть?


sniknik   (2002-11-19 22:45:00) [41]

Fantasist © (19.11.02 22:02)
> проблема в ADO в потоках?

не, уже давно в потоках пользую, проблем не замечал.


Fantasist   (2002-11-19 22:02:00) [42]

Не, iZEN, так нельзя, нам ведь жутко интересно, что же за глюк там сидит. :) А сами мы посмотреть не можем - он у вас.
То есть точно известно, что проблема в ADO в потоках? Утилитку пользовал, на которую я ссылку кинул? По ней можно отследить создаются ли сервера и в какой последовательности.


iZEN   (2002-11-19 13:12:00) [43]

Видимо, придётся поднимать как сервис любимую Java Virtual Machine и работать через JDBC и JNI.


iZEN   (2002-11-19 13:06:00) [44]

Для Polevi © (19.11.02 11:55).

Увы. Ах и ох. Ничего такого не вышло. Перепробовал различные способы инициализации - ноль.


iZEN   (2002-11-19 12:47:00) [45]

Для Polevi © (19.11.02 11:55).

Дело в том, что OLEInitialize(nil); CoInitialize(nil) и т.д. я делаю в секции initializeмодуля (пробовал разные варианты) - это должно срабатывать перед инициализацией любого приложения, но почему-то для ADO нет.
Хотя попробую Ваш способ. О результатах сообщу.


iZEN   (2002-11-19 12:44:00) [46]

Для DOOMin (19.11.02 12:06).
Насколько я понял из задачи ее можно решить без потоков.

Увы, нельзя. Это - промышленное приложение. Данные должны быть гарантировано обработаны с допустимым уровнем устойчивости. Например, нет доступа к архиву на время его обновления сторонним приложением, что делать? Кидать? Нет! Будем ждать и получать доступ: на это 5 попыток. То, что предлагаете Вы, - просто "на любителя". Это я уже прошёл и поимел шишек.
Кстати, я не использую TTimer. Причина: не нужно - нити могут приостанавливаться (Suspend) по внутренней логике, есть привязка к машинному времени через функции Now() и Sleep(...).


DOOMin   (2002-11-19 12:06:00) [47]

Я только не понял зачем все это делать в потоках, если данные изменяются раз в 30 минут? Почему нельзя сделать обячную обработку по таймеру? У меня уже больше года работает 2 сервиса, использующие ADO. В одном используется Datamodule, а в другом компоненты живут прямо в контейнере TService. Единственная специфика это вызов Coinitialize(nil) и то что я использую windows security for MSSQL и поэтому сервис должен быть запущен не от localsystem, а от какой-то учетной записи с правами доступа. Больше проблем не замечено. Скорее всего проблемы именно в работе ADO в потоке. Насколько я понял из задачи ее можно решить без потоков.


Polevi   (2002-11-19 11:55:00) [48]

1 поток - ServiceStart
инициировали COM, создали экземпляр Connection и передаем его в другой поток, как я понимаю ????

Writer.SetConnection(Connection);

надо передавать строку инициализации соеджинения в Writer, в его потоке делать CoIni.. и после этого создавать Connection


iZEN   (2002-11-19 11:48:00) [49]

Для sniknik © (19.11.02 11:21).

Суть проблемы такова.
1. Имеется архив с данными (не важно какой), на подобие базы данных.
2. Этот архив изменяется в реальном времени через каждые 30 минут.
3. Доступ к архиву осуществляется через собственный API на Object Pascal-е.
4. Я пишу сервис Win32 реального времени конвертации данных из этого архива в современную РСУБД (MS SQL Server 2000, IBPhoenix Firebird и т.д.)
5. Используются компоненты доступа ADO (стандартный доступ к РСУБД). Используются только обычные операторы SQL без специфических мелочей: delete from <table> where (...), insert into <table> values (...).
6. Данные из архива читаются, но не могут быть занесены в РСУБД по причине неинициализации ADO в сервисе - в обычных консольных и оконных приложениях это проходит нормально.
7. Задействуется механизм многопоточности Delphi, стэк, и критическая секция: одна нить читает данные, заносит их в стэк, другая нить читает данные из стэка и конвертирует в РСУБД с помощью SQL-запросов, стэк охраняется критической секцией.
8. Нигде не используются прямые вызовы WinAPI. Всё построено на стандартных классах VCL: TThread, TCriticalSection, TStack и т.д.


sniknik   (2002-11-19 11:21:00) [50]

очень специфический, не работает - основа секретности! :-)

ну нет так нет, если напишу когданибудь рабочий сервис сообщу.


iZEN   (2002-11-19 11:16:00) [51]

Для sniknik © (19.11.02 11:14).
Извините, не могу.
Это специфический сервис конвертации для промышленного приложения.
Думаю, суть обрисовал вполне полно (см. выше).
Возникнут вопросы - задавайте.


sniknik   (2002-11-19 11:14:00) [52]

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

одна голова хорошо,... а с мозгами лутше. :о))


iZEN   (2002-11-19 10:56:00) [53]

Бесполезно, ребята.
По-всякому пробовал:
тасовал OLEInitialize(nil); CoInitialize(nil); и парные процедуры, вызывал одно без другого, в секции инициализации модуля/нити и т.д. - бесполезно.
Сервис не хочет стартовать. Что ему не хватает? Мозгов чьих-то, очевидно. :(


Fantasist   (2002-11-18 00:25:00) [54]

Интересная проблема. В принципе, на использование COM серверов ограничений не накладывалось, разве только что правами доступа. Но и компоненты, на первый взгляд, делают всего лишь простую оболочку над ADO серверами, какой в них интересно можно глюк запихнуть? Эх, жаль NT нет, не могу посмотреть!

Попробуй создавать компоненты в том же потоке, что и работает с ними. Все-таки CoCreateInstance(точнее CoGetClassObject) делает больше, чем просто подгружает dll в память и вызывает DllGetClassObject. И в каждом потоке надо не забывать вызывать CoInitialize. И еще может эта утилитка поможет разобраться:
http://www.develop.com/hp/jasonw/comspy/default.htm


asmith   (2002-11-17 20:40:00) [55]

Нашел старые сорсы - делали такое (в сервисе ADO-компоненты).
1. Сервис на основе класса TService
2. В обработчике события ServiceExecute создавали поток, порождннный от класса TThread
3. В методе Execute потокового класса пишем, как обычно:
CoInitialize(nil);
...
try
FServer := ReadStringSetting(strServerSetting);
FDB := ReadStringSetting(strDBSetting);
FConn := TADOConnection.Create(nil);
FConn.LoginPrompt := False;
FConn.ConnectionString := Format(ыяConnString, [FDB, FServer]);
FConn.Open();
except
on E: Exception do
Log.Error(Format(errDBConnect, [FServer, E.Message]), False);
end;
...
// тело потока
...
CoUninitialize;
Это у нас работает.


sniknik   (2002-11-17 16:53:00) [56]

у тебя OLEInitialize(nil); делается а CoInitialize(nil); нет. Может в этом причина?

Вообще есть проги сервисы на Delphi писаные и со стандартными ADO компонентами, как минимум 1 такую знаю (правда исходников нет :( ), т.е. в принципе возможно.


asmith   (2002-11-16 15:22:00) [57]

Да, там какая-то проблема. Мы вышли из тупика, отказавшись от ADO-компонентов и перешли на интерфейсы ADO. Импортировали библиотеку типов, почистили ее от ненужных вещей (без этого размер исполняемого модуля был слишком велик, все писалось на API для достижения минимального размера)и далее юзали прямо интерфейса _Connection, _Command и другие.


BlackTiger   (2002-11-15 15:57:00) [58]

Сам с этим бился, то ли я чего-то не понял, то ли - ОБЛОМ.

Кое что работало, когда я в сервис пихал форму, и уже на форму кидал адошные контролы, не создавая их налету.
Но все равно нифига не работало - благо был под рукой интерфейс прямого доступа к базе.

У меня была проблема, что именно в сервисе ADO-компоненты просто отказывались инициализироваться (писал свой лог-файл перед вызовом каждой строки кода - только так и нашел), чего то им не хватало.


iZEN   (2002-11-15 15:24:00) [59]

>>>iZEN © (15.11.02 15:23)
>>>Компоненты ADO в консольном приложении. :[
>>>Возможно ли такое в принципе?

оопс...
Следует читать так:
"Компоненты ADO в сервисном приложении. :[
Возможно ли такое в принципе?"


Страницы:   1 2 3

Наверх

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