Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Corba";
Текущий архив: 2010.10.31;
Скачать: [xml.tar.bz2];

Вниз

сервис и ADO (многопотоковый COM)   Найти похожие ветки 

 
truegosha   (2007-01-19 16:33) [0]

Объясню название темы моего сообщения. ADO ведь реализовано как COM объект. Поэтому решил обратиться именно сюда, а не в форум по базам. Ошибка очень специфичная. Но может кто сталкивался...
На Delphi 6 писал службу с использованием API-функций. Служба эта - сервер приложений, среднее звено в трехзвенке. База MSSQL 2000. Служба многопоточная - главный поток, рабочий поток и следящий за рабочим. Рабочий поток создавал так:
hWorkTread := CreateThread(nil, 0, @ServerProc, @StatusHandle, 0, Dummy);

Вот процедура рабочего потока:
procedure ServerProc (Param: Pointer); stdcall;
var
 WorkThrStuff: TWorkThrStuff;
 client: TSimpleClient;
 cIE: HResult;
begin
 cIE := CoInitializeEx(nil, COINIT_MULTITHREADED);
 WorkThrStuff := TWorkThrStuff.Create;
 while bWork do
 begin
   if counter = 60 then
   begin
     client := nil;
     WorkThrStuff.RefreshState(client);
     counter := 1;
   end
   else counter := counter + 1;
   Sleep(1000);
 end;
 WorkThrStuff.Destroy;
 if Succeeded(cIE) then CoUninitialize;
end;

Вот кусок главного потока, который обрабатывает запросы SCM:
 while Status.dwCurrentState <> SERVICE_STOPPED do
 begin
   if not firsttime then
   begin
     if fdwControl = SERVICE_CONTROL_INTERROGATE then NotifyState
     else if dwSrvCtrlToPend[fdwControl] <> 0 then
     begin
       NotifyPend(fdwControl);
       if dwSrvCtrlToPend[fdwControl] = SERVICE_STOP_PENDING then
       begin
         bWork := false;
         if WaitForSingleObject(hControlTread, INFINITE) <> WAIT_OBJECT_0 then
         begin
           MyMsg[0]:="Остановка выполняется с ошибкой!";
           ReportEvent(EventLog, EVENTLOG_WARNING_TYPE, 0, 0, nil, 1, 0, @MyMsg, nil);
         end
         else
         begin
           CloseHandle(hControlTread);
           hControlTread := 0;
         end;
         if WaitForSingleObject(hWorkTread, INFINITE) <> WAIT_OBJECT_0 then
         begin
           MyMsg[0]:="Остановка выполняется с ошибкой!";
           ReportEvent(EventLog, EVENTLOG_WARNING_TYPE, 0, 0, nil, 1, 0, @MyMsg, nil);
         end
         else
         begin
           CloseHandle(hWorkTread);
           hWorkTread := 0;
         end;
       end;
       if dwSrvPendToState[Status.dwCurrentState] <> 0 then NotifyState;
     end;
   end;
   if bWork and (fdwControl = WORKTHREAD_CRASH) then
   begin
     MyMsg[0]:="Рабочий поток упал! Перезапуск потока!";
     ReportEvent(EventLog, EVENTLOG_ERROR_TYPE, 0, 0, nil, 1, 0, @MyMsg, nil);
     counter := 1;
     hWorkTread := CreateThread(nil, 0, @ServerProc, @StatusHandle, 0, Dummy);
   end;
   if Status.dwCurrentState <> SERVICE_STOPPED then
   begin
     GetQueuedCompletionStatus(g_hIOCP, dwBytesTransferred, fdwCompKey, po, INFINITE);
     fdwControl := dwBytesTransferred;
     firsttime := false;
   end;
 end;

В рабочем потоке полным-полно ADO компонентов. Причем для каждого клиентского приложения, подключающегося к серверу, в рабочем потоке создается свой поток. Поэтому вызываю CoInitializeEx(nil, COINIT_MULTITHREADED);
А при выходе из рабочего потока вызываю if Succeeded(cIE) then CoUninitialize;
На Windows 2000 работает без ошибок. А на XP после остановки службы выдается ошибка в модуле unknown. Как я понимаю, unknown - это интерфейс COM.
Где-то читал, что CoUninitialize нужно вызывать только для процесса, а не для потоков. Пробовал и так. Вызывал в самом конце программы. Не помогло. Заказчик, как на зло собирается ставить службу на XP.
Уже все варианты что знал - перебрал. Помогите пожалуйста! Заранее спасибо!


 
tesseract ©   (2007-01-21 13:14) [1]

> Как я понимаю, unknown - это интерфейс COM.

iUnknown  - это базовый интерфейс, существует во всем COM-объектах. Попробуй отладчиком посмотреть, где ошибка.


 
Polevi ©   (2007-01-23 08:05) [2]

попробуй убрать
if Succeeded(cIE) then CoUninitialize;


 
Сергей М. ©   (2007-01-23 10:41) [3]


> Рабочий поток создавал так:
> hWorkTread := CreateThread(


Нельзя так делать.
Рано или поздно при таком способе нахватаешь "глюков" по самое нехочу.

Используй BeginThread().


 
truegosha   (2007-01-24 10:01) [4]

Спасибо всем за ответы!
BeginThread() помогло!!!



Страницы: 1 вся ветка

Форум: "Corba";
Текущий архив: 2010.10.31;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.46 MB
Время: 0.003 c
8-1207514958
nuflin
2008-04-07 00:49
2010.10.31
мировое освещение


15-1279926253
Германн
2010-07-24 03:04
2010.10.31
Бред с XPManifest


2-1281441209
George
2010-08-10 15:53
2010.10.31
Проблемы с коннектом с Firebird


2-1281087136
Xmen
2010-08-06 13:32
2010.10.31
Сохранение Jpg файлов в базе Оракла


2-1281452943
DROWSY
2010-08-10 19:09
2010.10.31
Какая процедура отменяет изменения в текущей записи TIBDataSet,





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский