Ho creato alcuni servizi in Delphi 7 e non ho avuto questo problema. Ora che ho avviato una nuova app di servizio in XE2, non si arresterà correttamente. Non so se è qualcosa che sto facendo male o se potrebbe essere un bug nei servizi XE2.Delphi XE2 Il servizio non si arresta correttamente
La procedura di esecuzione assomiglia a questo:
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;
ho mai un'eccezione, come si può vedere annoto alcuna eccezione. PostLog
salva in un file INI, che funziona bene. Ora uso i componenti ADO, quindi uso CoInitialize()
e CoUninitialize
. Si connette al DB e fa il suo lavoro correttamente. Il problema si verifica solo quando interrompo questo servizio. Finestre mi dà il seguente messaggio:
Poi il servizio continua. Devo fermarlo una seconda volta. La seconda volta che si ferma, ma con il seguente messaggio:
Il file di registro indica che il servizio ha fatto con successo gratuito (OnDestroy
evento è stato registrato), ma non ha mai smesso di successo (OnStop
non è mai stato registrato).
Nel mio codice precedente, ho due procedure Startup
e Cleanup
. Questi semplicemente creare/distruggere e inizializzare/annullare l'inizializzazione mie cose necessarie ...
procedure TMySvc.Startup;
begin
FUpdateThread:= TMyUpdateThread.Create;
FUpdateThread.OnLog:= LogUpdate;
FUpdateThread.Resume;
end;
procedure TMySvc.Cleanup;
begin
FUpdateThread.Terminate;
end;
Come potete vedere, ho un thread in esecuzione secondario. Questo servizio ha in realtà numerosi thread in esecuzione in questo modo e il thread del servizio principale registra solo gli eventi da ciascun thread. Ogni thread ha responsabilità diverse. I thread stanno riportando correttamente, e sono anche stati terminati correttamente.
Che cosa potrebbe causare questo arresto anomalo? Se il mio codice inserito non espone nulla, allora posso postare più di codice in seguito - semplicemente a 'convertire' a causa della denominazione interna, ecc
EDIT
Ho appena iniziato a progetto nuovo servizio Delphi XE2 e hanno lo stesso problema. Questo è tutto il mio codice qui sotto:
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.
È improbabile che si sia verificato un errore nel codice Delphi.Riesci a ridurlo a una riproduzione minima. –
^^ +1. Sembra che il thread non termini mai, quindi il timeout in SCM – whosrdaddy
IMHO la routine TMySvc.Cleanup è destinata a creare problemi. Si termina FUpdateThread ma non si sa quando è realmente terminato. Aggiungi un WaitFor o utilizza un oggetto synchro per rilevare correttamente la terminazione. Guarda qui per maggiori informazioni: http://www.eonclash.com/Tutorials/Multithreading/MartinHarvey1.1/Ch5.html – whosrdaddy