He creado algunos servicios en Delphi 7 y no tuve este problema. Ahora que comencé una nueva aplicación de servicio en XE2, no se detendrá correctamente. No sé si es algo que estoy haciendo mal o si podría ser un error en los servicios de XE2.Delphi XE2 El servicio no se detiene correctamente
procedimiento La ejecución se parece a esto:
procedure TMySvc.ServiceExecute(Sender: TService);
begin
try
CoInitialize(nil);
Startup;
try
while not Terminated do begin
DoSomething; //Problem persists even when nothing's here
end;
finally
Cleanup;
CoUninitialize;
end;
except
on e: exception do begin
PostLog('EXCEPTION in Execute: '+e.Message);
end;
end;
end;
no tengo una excepción, como se puede ver que registra ninguna excepción. PostLog
guarda en un archivo INI, que funciona bien. Ahora uso componentes ADO, así que uso CoInitialize()
y CoUninitialize
. Se conecta a la base de datos y hace su trabajo correctamente. El problema solo ocurre cuando dejo este servicio. Windows me da el siguiente mensaje:
A continuación, el servicio continúa. Tengo que detenerlo por segunda vez. La segunda vez que se detiene, pero con el siguiente mensaje:
El archivo de registro indica que el servicio lo hizo con éxito libre (OnDestroy
evento se registra) pero nunca se detuvo con éxito (OnStop
nunca fue registrada).
En mi código anterior, tengo dos procedimientos Startup
y Cleanup
. Estos simplemente crear/destruir e inicializar/desinicializar mis cosas necesarias ...
procedure TMySvc.Startup;
begin
FUpdateThread:= TMyUpdateThread.Create;
FUpdateThread.OnLog:= LogUpdate;
FUpdateThread.Resume;
end;
procedure TMySvc.Cleanup;
begin
FUpdateThread.Terminate;
end;
Como se puede ver, tengo una ejecución subproceso secundario. De hecho, este servicio tiene numerosos hilos que funcionan así, y el hilo de servicio principal solo está registrando los eventos de cada hilo. Cada hilo tiene diferentes responsabilidades. Los subprocesos informan correctamente y también se cancelan correctamente.
¿Qué podría estar causando esta falla en la detención? Si mi código publicado no expone nada, entonces me pueden enviar más tarde código - sólo hay que 'convertir' a causa de denominación interna, etc.
EDITARacabo de comenzar proyecto nuevo servicio
en Delphi XE2, y tienen el mismo problema. Todo esto es mi código de abajo:
unit JDSvc;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Classes, JDSvcMgr;
type
TJDService = class(TService)
procedure ServiceExecute(Sender: TService);
private
FAfterInstall: TServiceEvent;
public
function GetServiceController: TServiceController; override;
end;
var
JDService: TJDService;
implementation
{$R *.DFM}
procedure ServiceController(CtrlCode: DWord); stdcall;
begin
JDService.Controller(CtrlCode);
end;
function TJDService.GetServiceController: TServiceController;
begin
Result := ServiceController;
end;
procedure TJDService.ServiceExecute(Sender: TService);
begin
while not Terminated do begin
end;
end;
end.
No es probable que sea un error en el código Delphi.¿Puedes reducir esto a una reproducción mínima? –
^^ +1. Parece que su hilo nunca termina, por lo tanto, el tiempo de espera en SCM – whosrdaddy
en mi humilde opinión la rutina TMySvc.Cleanup está destinada a crear problemas. Usted termina FUpdateThread pero no sabe cuándo realmente se termina. Agregue un WaitFor o use un objeto sincronizado para detectar la terminación correctamente. Mire aquí para obtener más información: http://www.eonclash.com/Tutorials/Multithreading/MartinHarvey1.1/Ch5.html – whosrdaddy