Entwickler-Ecke
Windows API - Dienst mit hoher CPU Auslastung
Jakane - Di 24.02.15 13:57
Titel: Dienst mit hoher CPU Auslastung
Hallo Delphi-Helfer
Ich habe einen Dienst mit Timer und dieser Timer soll bestimmte Dinge prüfen und erledigen.
Der Timer tut das mitlerweile Problemlos.
Mein Problem ist, dass selbst wenn der Timer ausgeschaltet ist,
ServiceExecute permanent arbeitet und damit auf Leistungsschwachen PCs zu bis zu 70% Auslastung führt.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| procedure TFÜDienst.ServiceExecute(Sender: TService); begin _FÜ.TimerZeit.Enabled := True;
while not Terminated do begin ServiceThread.ProcessRequests(False); end;
_FÜ.TimerZeit.Enabled := False; end; |
Ich habe es mit Sleep(1) probiert, bei mir funktioniert es, aber dafür kann ich den Dienst nicht anhalten oder beenden (verständlicherweise)
aber auf dem schwachen PC startet der Dienst garnicht, weil er nicht rechtzeitig antwortet.
Kann man dem ServiceExecute beibringen nur auf den Timer zu warten, aber auch sich zu beenden, wenn ich den Dienst beenden will?
Narses - Di 24.02.15 16:27
Moin!
Probier das mal so (ungetestet):
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| procedure TFÜDienst.ServiceExecute(Sender: TService); const WAITFOR_MS = 1000; var Tick: DWord; Event: THandle; begin _FÜ.TimerZeit.Enabled := True; Event := CreateEvent(nil, False, False, nil); try while not Terminated and (MsgWaitForMultipleObjects(1, Event, False, WAITFOR_MS, QS_ALLINPUT) <> WAIT_TIMEOUT) do begin ServiceThread.ProcessRequests(False); end; finally CloseHandle(Event); end; _FÜ.TimerZeit.Enabled := False; end; |
cu
Narses
Jakane - Mi 25.02.15 11:36
Narses hat folgendes geschrieben : |
Moin!
Probier das mal so (ungetestet):
cu
Narses |
Ich habe es getestet. Aber wie bei Sleep auch, bekomme ich die Meldung, das der Dienst nicht rechtzeitig antwortet.
Jakane - Do 26.02.15 19:37
Gibt es niemanden der das Problem kennt und lösen kann?
Order tritt das echt nur bei mir auf? :(
Narses - Do 26.02.15 20:12
Moin!
Ich probier gleich nochmal was aus :les: (das hatte ich auch schonmal, ich find nur das Projekt nicht wieder... :roll:).
cu
Narses
Narses - Do 26.02.15 23:32
Moin!
Hab mal eben ein Test-Projekt aufgesetzt:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs, ExtCtrls;
const LOGFILE_NAME = 'C:\test.log';
type TService1 = class(TService) Timer1: TTimer; procedure ServiceCreate(Sender: TObject); procedure ServiceStart(Sender: TService; var Started: Boolean); procedure ServiceExecute(Sender: TService); procedure ServiceStop(Sender: TService; var Stopped: Boolean); procedure Timer1Timer(Sender: TObject); private public function GetServiceController: TServiceController; override; end;
var Service1: TService1;
implementation
{$R *.DFM}
procedure ServiceController(CtrlCode: DWord); stdcall; begin Service1.Controller(CtrlCode); end;
function TService1.GetServiceController: TServiceController; begin Result := ServiceController; end;
procedure TService1.ServiceCreate(Sender: TObject); var LogFile: TFileStream; begin if NOT FileExists(LOGFILE_NAME) then begin LogFile := TFileStream.Create(LOGFILE_NAME, fmCreate); LogFile.Free; end; end;
procedure TService1.ServiceStart(Sender: TService; var Started: Boolean); begin Timer1.Enabled := TRUE; end;
procedure TService1.ServiceExecute(Sender: TService); begin while NOT Terminated do ServiceThread.ProcessRequests(TRUE); end;
procedure TService1.ServiceStop(Sender: TService; var Stopped: Boolean); begin Timer1.Enabled := FALSE; end;
procedure TService1.Timer1Timer(Sender: TObject); var LogFile: TFileStream; Msg: AnsiString; begin LogFile := TFileStream.Create(LOGFILE_NAME, fmOpenReadWrite or fmShareDenyWrite); try Msg := DateTimeToStr(Now)+#13#10; LogFile.Seek(0, soFromEnd); LogFile.Write(PAnsiChar(Msg)^, Length(Msg)); finally LogFile.Free; end; end;
end. |
Das tut was es soll und produziert bei mir auch keine hohe CPU-Last. :nixweiss:
cu
Narses
jaenicke - Fr 27.02.15 07:53
Der Unterschied ist, dass man mit True als Parameter für ProcessRequests wartet bis eine Nachricht zum Abarbeiten da ist, mit False aber nicht. Dadurch wird mit False die CPU Auslastung entsprechend hoch sein, wenn man nicht noch selbst eine kurze Wartezeit einbaut.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2024 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!