![]() |
Eigener Dienst beendet nicht korrekt...
Hi
Mein Dienst beendet manchmal korrekt, manchmal nicht. Nicht nur beim manuellen start/stop sondern auch beim Herunterfahren des PC's... Wenn ich den Dienst manuell beende erhalte ich manchmal die Meldung: "Dienst konnte nicht beendet werden" und die Function "Update Userinfo" wird nicht mehr ausgeführt. Beim Herunterfahren des PCs werden ja alle Dienste beendet, doch meiner scheint dies nicht korrekt zu tun, denn auch hier wird die Function "Update Userinfo" nicht immer ausgeführt.
Delphi-Quellcode:
Hier das Execute...
procedure TMeinDienst.ServiceShutdown(Sender: TService);
begin UpdateUserInfo(Username, false); LogFile.LOG(msg0009); end;
Delphi-Quellcode:
Bitte wirf doch mal ein Blick drauf.. PS: und wenn du gleich andere Sachen siehst die man anders strukturieren müsste, dann lass es mich wissen...
procedure TMeinDienst.ServiceExecute(Sender: TService);
begin //ShowMessage('OnExecute - begin'); while not Terminated do begin TRY // try to catch a user if Username <> '' then begin // AUTOSCAN // THIS SECTION IS FOR USER WHO JUST LOGGED IN if (Username <> GetSession) or (Welcome = False) then begin ChangeUser; if Username <> '' then // its important to get sure that the username has really been catched begin Welcome := True; LogFile.Log(msg0004+GetIPAddress); // check if the user already exists in the database CheckDBforUser(ADOQuery1,ADOStoredProc1); // Save to database that the user is logged in UpdateUserInfo(Username, true); // get all info from User Table "t_bb_user" ADOQuery3.Close; ADOQuery3.Parameters.ParamValues['@username'] := username; ADOQuery3.Open; // If the logged in user is not on the blacklist it will autoscan now if CheckUserOnBlacklist(Username) = False then begin // autostart scan now, but first get defined scan_type from db! case ADOQuery3scan_type.AsInteger of 0: begin ScanAndWriteToDB(True, stNoScanNoWrite); end; 1: begin ScanAndWriteToDB(True, stFullScanWriteJustRootFoldersSize); end; 2: begin ScanAndWriteToDB(True, stFullScanAndWrite); end; end; end else begin // user is on blacklist, but login info will be saved ScanAndWriteToDB(True, stNoScanNoWrite); LogFile.Log(Username+msg0016); end; // activate TCP server if not assigned(TCPServer) then ActivateTCPServer; end; end else if StartManScan then begin try // check if the user already exists in the database, else it will create him if Username <> '' then begin CheckDBforUser(ADOQuery1,ADOStoredProc1); ScanAndWriteToDB(False, stFullScanAndWrite); end; finally // its very important to reset the variable StartManScan StartManScan := False; // send to the requesting host that the scan is complete now... Connect; TCPClient.IOHandler.WriteLn(IntToStr(CmdScanFinished)); // disconnect Disconnect; end; end; end else begin ChangeUser; Welcome := False; end; EXCEPT on e:Exception do begin LogFile.LOG(msg0000+e.Message); // maby there are some tcp actions pending... Disconnect; if fulllog then LogFile.Log(msg0039); end; END; ServiceThread.ProcessRequests(False); Sleep(1000); end; //ShowMessage('OnExecute - end'); end; LG Cherry |
Re: Eigener Dienst beendet nicht korrekt...
Greift
Delphi-Quellcode:
auf eine DB zu, wenn ja dann musst du die Abhängigkeiten für diesen Dienst änder.
UpdateUserInfo(Username, false);
|
Re: Eigener Dienst beendet nicht korrekt...
Hallo,
Du greifst auf eine Datenbank zu, läuft die zufällig auf dem gleichen Rechner? Dann könnte es sein, dass die (zumindest beim Herunterfahren) vor Deinem Dienst beendet wurde. Soweit ich weiß ist die Reihenfolge, in der Dienste beim Runterfahren beendet werden, nicht definiert, daher mal das: geht / geht nicht. Das ist natürlich keine Erklärung für das manuelle Stoppen des Dienstes. Da Du eine Methode zum Loggen hast, schreib da mal etwas mehr mit in die Logdatei, z. B. vor jeden Funktions- bzw. Prozeduraufruf ala
Delphi-Quellcode:
Damit der Änderungsaufwand für diese Form des "von Hand debuggen" nicht zu groß wird, mache ich das meistens so:
LogFile.Log(msg4711+'vor ADOQuery.Open');
Am Anfang der Unit steht ein
Delphi-Quellcode:
das bei (hoffentlicher) Fehlerfreiheit auskommentiert wird. Das Loggen steht dann in der Form im Quelltext:
{$DEFINE VERBOSE}
Delphi-Quellcode:
Eventuell solltest Du dem Try-Finally-Block noch einen zusätzlichen Try-Except-Block gönnen, um dort auftretende Fehler loggen zu können.
{$IFDEF VERBOSE}
LogFile.Log(msg4711+'vor ADOQuery.Open') ;{$ENDIF} Ausgehend von Deinem geposteten Quelltext kann ich auf die Schnelle kein grundlegendes Problem erkennen. Da Du aber etliche Methoden aufrufst, könnte dort irgendwo ein "Hänger" sein, z. B. ein Timeout, dass höher ist, als die Wartezeit, die Deinem Dienst beim Beenden vom Betriebssystem gegönnt wird. Und wenn mehrere Methoden auf ein Timeout warten oder nur mit nicht allzu kurzen Wartezeiten zu tuen haben, könnte das zu diesem sporadischen Problem führen. |
Re: Eigener Dienst beendet nicht korrekt...
Danke für die schnelle Antworten. Erstmal:
Zitat:
Zitat:
Zitat:
|
Re: Eigener Dienst beendet nicht korrekt...
Zitat:
Nutzt Dein Dienst irgendwelche Daten (Dateien, Datenbanken, Server, Services...), die auf dem gleichen Rechner laufen? Wenn ja, musst Du sicherstellen, dass Dein Dienst vor den Anderen beendet wird. Die Datenbank dürfte hier jedoch schonmal nicht das Problem sein (da auf anderem Server). Was macht z. B. ScanAndWriteToDB und mit wem unterhält sich TCPClient.IOHandler.WriteLn(IntToStr(CmdScanFinish ed))? Sind das Sachen auf dem Rechner mit dem Dienst oder greifst Du auf andere Systeme zu? Wer wird mit Connect angesprochen? Dienstabhängigkeit einrichten unter Windows 2003 siehe hier: ![]() |
Re: Eigener Dienst beendet nicht korrekt...
Zitat:
Lokal: - Logfile auf "C:\Programme\MeinDienst\Logfile.log" - Prozeduren die auf Lokale Dateien zugreiffen (nur Lesen) {ScanAndWriteToDB} - Prozeduren die Registry Keys lesen (nur lesen) - Prozedur die angemeldeten Benutzer ausliest Extern: - MSSQL DB {ScanAndWriteToDB} - Auswertungsprogramm das von einem anderen Rechner aus läuft {TCP/IP} Zitat:
|
Re: Eigener Dienst beendet nicht korrekt...
ServiceShutdown wird nur aufgerufen, wenn der Dienst von außen beendet werden soll, aber nicht wenn er sich beendet.
In ServiceShutdown musst du deine Prozedur ServiceExecute veranlassen aus der while-Schleife zu springen. Dann kannst du am Ende von ServiceExecute dein Logging machen. Es sieht so aus, als ob es nur deshalb manchmal geht, weil Windows deinen Dienst abschießt, da er nicht schnell genug aus ServiceExecute austritt. Ich sehe nämlich garkein Endbedingung. |
Re: Eigener Dienst beendet nicht korrekt...
Hallo,
verschieb mal Deine Methode
Delphi-Quellcode:
nach
procedure TMeinDienst.ServiceShutdown(Sender: TService);
begin UpdateUserInfo(Username, false); LogFile.LOG(msg0009); end;
Delphi-Quellcode:
procedure TMeinDienst.ServiceStop(Sender: TService; var Stopped: Boolean);
begin UpdateUserInfo(Username, false); LogFile.LOG(msg0009); Stopped := True; end; |
Re: Eigener Dienst beendet nicht korrekt...
Zitat:
Zitat:
|
Re: Eigener Dienst beendet nicht korrekt...
hast du das da:
ServiceThread.ProcessRequests(False); schonmal so hingeschrieben: ServiceThread.ProcessRequests(True); ? Edit: Ah ne das war ja was anderes -.- Wie wäre es mit debuggen? Aus der IDE mit dem prozess verbinden und dann schauen was wo wie hängt |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:39 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz