|
Registriert seit: 14. Jul 2003 Ort: Flintbek 810 Beiträge Delphi XE2 Professional |
#1
Hi Leute,
ich bin in unserer Firma ein Tool "Server Monitor" programmiert für ca. 70 Server. Die Aufgaben sind: 1. Online Check 2. Informationen mit Hilfe von WMI sammeln pro Server 3. Dienste von verschiedenen Server überwachen (mit Hilfe von WMI) Das Programm läuft schon wunderbar. Ich habe nur das Problem, dass sich das Programm aufhängt nach ca. 2 Tagen. Nichts reagiert mehr. Folgendes läuft im Hintergrund: 1. Alle 10 Sekunden werden die Server auf ihren Status geprüft ==> 70 Threads werden dazu erzeugt (Ping Funktion)...Dauer aller Threads = 5 Sekunden 2. Alle 20 Sekunden werden die Dienste überprüft ==> 20 Threads (WMI Abfrage)... Dauer aller Threads = 10 Sekunden 3. Alle 5 Minuten werden alle möglichen Daten (z.B.: Seriennummer, CPU, RAM, etc.) abgefragt ==> 70 Threads werden erzeugt (WMI Abfragen)...Dauer aller Threads = 1 Minute Mir ist aufgefallen, dass die Ping Threads sich sauber beenden und keiner übrig bleibt. Bei den anderen kommt es vor, dass sie vereinzelt stehen bleiben und sich sogar vermehren. Ich habe nur eine Thread Unit. Ich benutze TThread. Muss ich eventuell meine Logik ändern? Wie würdet ihr soetwas realsieren? Aufruf der Threads durch den Timer am Beispiel der Diensteüberwachung:
Delphi-Quellcode:
Thread Unit:
procedure Tfrm_main.CheckServiceStatusThreadTerminate(Sender: TObject);
begin if ThreadCount_ServiceCheck = ThreadMax_ServiceCheck then begin ThreadsRunning_ServiceCheck := False; lbl_overview_servicecheck.Caption := FormatDateTime('dd. mmmm yyyy hh:nn:ss', now); if cb_setup_servicestatusactive.Checked = True then timer_checkservicestatus.Enabled := True; end; ThreadCount_ServiceCheck := ThreadCount_ServiceCheck + 1; end; procedure Tfrm_main.timer_checkservicestatusTimer(Sender: TObject); var i : Integer; Thread : MyThread; begin while ThreadsRunning_ServerInfoToXML = True do Application.ProcessMessages; ThreadMax_ServiceCheck := lv_service.Items.Count - 1; ThreadsRunning_ServiceCheck := True; ThreadCount_ServiceCheck := 0; for i := 0 to ThreadMax_ServiceCheck do begin timer_checkservicestatus.Enabled := False; ThreadsRunning_ServiceCheck := True; Thread := MyThread.Create(True); Thread.art := 'CheckServiceStatus'; Thread.user := edt_setup_user.Text; Thread.pwd := edt_setup_password.Text; Thread.lvid := i; Thread.service := lv_service.Items[i].SubItems[0]; Thread.servicerestart := lv_service.Items[i].SubItems[2]; Thread.server := lv_service.Items[i].SubItems[3]; Thread.lastStatus := lv_service.Items[i].SubItemImages[4]; Thread.OnTerminate := CheckServiceStatusThreadTerminate; Thread.FreeOnTerminate := True; Thread.Resume; end; end;
Delphi-Quellcode:
unit uThread;
interface uses Classes, SysUtils, MSXML2_TLB, ActiveX, Dialogs, uMain, uServer, ComCtrls, uHostAlive, WbemScripting_TLB, Variants; type MyThread = class(TThread) private { Private-Deklarationen } protected procedure Execute; override; procedure CheckServerStatus; procedure ServerStatusToListView; procedure CheckServiceStatus; procedure ServiceStatusToListView; procedure ServerInformationToXML; public { Public-Deklarationen } art : String; lvid : Integer; lastStatus : Integer; server : String; sid : String; curStatus : String; user : String; pwd : String; service : String; servicerestart : String; end; implementation uses uHostSocketAlive, DateUtils; { Wichtig: Methoden und Eigenschaften von Objekten in visuellen Komponenten dürfen nur in einer Methode namens Synchronize aufgerufen werden, z.B. Synchronize(UpdateCaption); und UpdateCaption könnte folgendermaßen aussehen: procedure MyThread.UpdateCaption; begin Form1.Caption := 'Aktualisiert in einem Thread'; end; } { MyThread } procedure MyThread.Execute; begin CoInitialize(nil); try if art = 'CheckServerStatus' then CheckServerStatus; if art = 'CheckServiceStatus' then CheckServiceStatus; if (art = 'ServerInformationToXML') and (lastStatus = 1) then ServerInformationToXML; except on e: exception do begin // mache hier irgendetwas mit dem Fehler. end; end; CoUnInitialize(); end; procedure MyThread.CheckServerStatus; var i : Integer; max : Integer; begin // Verbindungsversuche max := 3; for i := 0 to max - 1 do begin if IsHostAlive(Server) = True then begin curStatus := '1'; //Server Online break; end else curStatus := '2'; //Server Offline end; Synchronize(ServerStatusToListView); end; procedure MyThread.ServerStatusToListView; begin with frm_main.lv_server do begin case lastStatus of 1 : begin if curStatus = '2' then begin Items[lvid].ImageIndex := 2; if frm_main.FirstStart = False then Items[lvid].SubItems[1] := 'off'; end; end; 2 : begin if curStatus = '1' then begin Items[lvid].ImageIndex := 1; if frm_main.FirstStart = False then Items[lvid].SubItems[1] := 'on'; end; end; end; end; end; procedure MyThread.CheckServiceStatus; var SWbemLocator1 : ISWbemLocator; aSrv : ISWbemServices; vNVS : OleVariant; aObjSet : ISWbemObjectSet; aNVSDummy : IDispatch; pEnum : IEnumVARIANT; vOut : OleVariant; dwRetrieved : LongWord; hRes : HResult; begin try SWbemLocator1 := CoSWbemLocator.Create; // Für lokale Computer darf kein Benutzer und Passwort verwendet werden if UpperCase(server) <> UpperCase(GetEnvironmentVariable('COMPUTERNAME')) then aSrv := SWbemLocator1.ConnectServer(server,'root\cimv2',user, pwd,'','',0,vNVS) else aSrv := SWbemLocator1.ConnectServer(server,'root\cimv2','','','','',0,vNVS); aObjSet := aSrv.ExecQuery('Select * from Win32_Service Where Name = "' +service+'"','WQL', 0, aNVSDummy); pEnum := aObjSet.Get__NewEnum as IEnumVARIANT; hRes := pEnum.Next(1, vOut, dwRetrieved); if hRes = S_OK then curStatus := VarToStr(vOut.State); Free; Except curStatus := ''; end; Synchronize(ServiceStatusToListView); end; procedure MyThread.ServiceStatusToListView; begin with frm_main.lv_service do begin case lastStatus of 16 : begin if curStatus <> 'Running' then begin Items[lvid].SubItemImages[4] := 17; if frm_main.FirstStart = False then //Items[lvid].SubItems[6] := 'down'; end; end; 17 : begin if curStatus = 'Running' then begin Items[lvid].SubItemImages[4] := 16; if frm_main.FirstStart = False then //Items[lvid].SubItems[6] := 'up'; end; end; 0,18 : begin if curStatus = 'Running' then Items[lvid].SubItemImages[4] := 16 else Items[lvid].SubItemImages[4] := 17; end; end; end; end; // Gekürzter Quellcode procedure MyThread.ServerInformationToXML; var ... begin ... try SWbemLocator1 := CoSWbemLocator.Create; // Für lokale Computer darf kein Benutzer und Passwort verwendet werden if UpperCase(server) <> UpperCase(GetEnvironmentVariable('COMPUTERNAME')) then aSrv := SWbemLocator1.ConnectServer(server,'root\cimv2',user, pwd,'','',0,vNVS) else aSrv := SWbemLocator1.ConnectServer(server,'root\cimv2','','','','',0,vNVS); //*** System Summary *** aObjSet := aSrv.ExecQuery('Select * from Win32_ComputerSystem','WQL', 0, aNVSDummy); ... //*** Operation System *** aObjSet := aSrv.ExecQuery('Select * from Win32_OperatingSystem','WQL', 0, aNVSDummy); ... //*** Prozessor Information *** aObjSet := aSrv.ExecQuery('Select * from Win32_Processor','WQL', 0, aNVSDummy); ... //*** Memory Information *** aObjSet := aSrv.ExecQuery('Select * from Win32_PhysicalMemory','WQL', 0, aNVSDummy); ... //*** Network Information *** aObjSet := aSrv.ExecQuery('Select * from Win32_NetworkAdapterConfiguration where IPEnabled = true','WQL', 0, aNVSDummy); ... //*** Storage Information *** aObjSet := aSrv.ExecQuery('Select * from Win32_LogicalDisk Where DriveType = 3','WQL', 0, aNVSDummy); ... Except // end; end; end. |
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |