TMSServiceBroker перестал работать в составе службы Windows
Добавлено: Пн 19 окт 2015 09:33
Здравствуйте!
Пытаюсь перейти на SDAC версии 7.2.8 с версии 6.11.23. Использую Delphi XE6.
Существует служба Windows (TService), которая с помощью компоненты TMSServiceBroker отслеживает сообщения в очереди брокера, отправляемые туда по расписанию заданиями SQL-сервера.
При компиляции этой службы на SDAC v7 сообщения из очереди забираются, но их обработка не выполняется (событие MSServiceBrokerBeginConversation не вызывается).
Поизучал ваши исходники и выяснил, что перестал работать таймер, по которому обрабатывались полученные сообщения из очереди. TMSServiceBroker использует отдельный поток для обработки полученных сообщений - класс TCRThreadWrapper.
1. В методе TCRThreadWrapper.SetTimer таймер теперь активируется только при условии выполнения в главном потоке (используется функция IsMainThread)! В случае службы Windows таймер не запускается никогда:
2. Собственно, метод SetTimer также не вызывается. В конструкторе используется та же проверка IsMainThread:
Но список NeedToSetTimerList обрабатывается только в методе DoTimer, который вызывается по таймеру, создаваемому в методе SetTimer. Вот так круг замкнулся.
Помогите, пожалуйста. Как теперь использовать ваш компонент в службе Windows?
Пытаюсь перейти на SDAC версии 7.2.8 с версии 6.11.23. Использую Delphi XE6.
Существует служба Windows (TService), которая с помощью компоненты TMSServiceBroker отслеживает сообщения в очереди брокера, отправляемые туда по расписанию заданиями SQL-сервера.
При компиляции этой службы на SDAC v7 сообщения из очереди забираются, но их обработка не выполняется (событие MSServiceBrokerBeginConversation не вызывается).
Поизучал ваши исходники и выяснил, что перестал работать таймер, по которому обрабатывались полученные сообщения из очереди. TMSServiceBroker использует отдельный поток для обработки полученных сообщений - класс TCRThreadWrapper.
1. В методе TCRThreadWrapper.SetTimer таймер теперь активируется только при условии выполнения в главном потоке (используется функция IsMainThread)! В случае службы Windows таймер не запускается никогда:
Код: Выделить всё
procedure TCRThreadWrapper.SetTimer;
const
USER_TIMER_MINIMUM = $A;
begin
if FTimer = nil then begin
FTimer := TCRTimer.Create(nil);
FTimer.Enabled := False;
FTimer.Interval := USER_TIMER_MINIMUM;
FTimer.OnTimer := DoTimer;
end;
Assert(not FTimer.Enabled);
if IsMainThread then
FTimer.Enabled := True;
end;
Код: Выделить всё
constructor TCRThreadWrapper.Create;
begin
inherited Create;
FLockState := {$IFDEF FPC}SyncObjs.{$ENDIF}TCriticalSection.Create;
FThreadState := tsSuspended;
FEvents := TThreadList.Create;
FSendEventProcessed := TEvent.Create(nil, True, False, '');
FThread := TCRThread.Create(Self);
if IsMainThread then
SetTimer
else
NeedToSetTimerList.Add(Self);
end;
Помогите, пожалуйста. Как теперь использовать ваш компонент в службе Windows?