Форум: "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