![]() |
WMI Threads 10 Stück fehler 5 ok.
Servus,
ich habe mir einen Thread gebastelt, der per WMI Daten abfragt und diese an die Main schickt.
Delphi-Quellcode:
Wenn ich jetzt nur 5 Threads aufrufe bekomme ich keinen Fehler.
var
wmi : TWMIThread; begin //OnWMIData -> procedure aus der Main wmi := TWMIThread.Create(OnWMIData, 'Win32_OperatingSystem', '', '', ''); //... Wenn ich aber alle 10 Aufrufe bekomme ich die Meldung Zitat:
Jetzt vermute ich das bei der WMI Abfrage was falsch läuft. Das ist die Execute vom Thread
Delphi-Quellcode:
Und das ist die Methode LoadClassInData
inherited;
CoInitialize(nil); WMIThreadCS.Enter; //<- global try wmi := LoadClassInData(fWMIClass, fWMIHost, fWMIUser, fWMIPass); finally WMIThreadCS.Leave; end; wmi.WMIClass := fWMIClass; try WMIThreadCS.Enter; if Assigned(fOnWMIData) then fOnWMIData(wmi); finally WMIThreadCS.Leave; end; for i:=0 to wmi.InstanceCount-1 do wmi.Instance[i].Free; OleUninitialize;
Delphi-Quellcode:
Ein wenig viel code, aber vielleicht kann mir ja einer weiterhelfen.
var
Locator: ISWbemLocator; Services: ISWbemServices; SObject: ISWbemObject; ObjSet: ISWbemObjectSet; SProp: ISWbemProperty; SPropSet: ISWbemPropertySet; Enum, propEnum: IEnumVariant; Value: Cardinal; TempObj: OleVariant; // SN: string; Count : integer; sValue : string; begin result.InstanceCount := 0; SetLength(result.Instance,0); try try result.Error := ''; Locator := CoSWbemLocator.Create; //Locator.Connect -> muss man die "verbindung" nicht auch wieder schließen? Services := Locator.ConnectServer(wmiHost, 'root\cimv2', lUser, lPasswort, '','', 0, nil); ObjSet := Services.ExecQuery('SELECT * FROM '+wmiClass+fWhere, 'WQL',wbemFlagReturnImmediately and wbemFlagForwardOnly , nil); Enum := (ObjSet._NewEnum) as IEnumVariant; while (Enum.Next(1, TempObj, Value) = S_OK) do begin SObject := IUnknown(tempObj) as ISWBemObject; SPropSet := SObject.Properties_; //me propEnum := (SPropSet._NewEnum) as IEnumVariant; //me SetLength(result.Instance,Length(result.Instance)+1); result.InstanceCount := result.InstanceCount +1; result.Instance[result.InstanceCount-1] := TStringList.Create; while (propEnum.Next(1, tempObj, Value) = S_OK) do //me begin SProp := IUnknown(tempObj) as SWBemProperty; //me if VarIsNull(SProp.Get_Value) then sValue := '<empty>' else case SProp.CIMType of wbemCimtypeSint8, wbemCimtypeUint8, wbemCimtypeSint16, wbemCimtypeUint16, wbemCimtypeSint32, wbemCimtypeUint32, wbemCimtypeSint64: if VarIsArray(SProp.Get_Value) then begin if VarArrayHighBound(SProp.Get_Value, 1) > 0 then for Count := 1 to VarArrayHighBound(SProp.Get_Value, 1) do sValue := sValue + ' ' + IntToStr(SProp.Get_Value[Count]); end else sValue := IntToStr(SProp.Get_Value); wbemCimtypeReal32, wbemCimtypeReal64: sValue := FloatToStr(SProp.Get_Value); wbemCimtypeBoolean: if SProp.Get_Value then sValue := 'True' else sValue := 'False'; wbemCimtypeString, wbemCimtypeUint64: if VarIsArray(SProp.Get_Value) then begin if VarArrayHighBound(SProp.Get_Value, 1) > 0 then for Count := 1 to VarArrayHighBound(SProp.Get_Value, 1) do sValue := sValue + ' ' + SProp.Get_Value[Count]; end else sValue := SProp.Get_Value; wbemCimtypeDatetime: sValue := SProp.Get_Value; wbemCimtypeReference: begin sValue := SProp.Get_Value; end; wbemCimtypeChar16: sValue := '<16-bit character>'; wbemCimtypeObject: sValue := '<CIM Object>'; end; //ende case //showmessage(SProp.Name+' '+result); result.Instance[result.InstanceCount-1].Add(SProp.Name+'='+sValue); sValue := ''; end; end; finally Locator := nil; Services := nil; end; except // Trap any exceptions (Not having WMI installed will cause one!) on exception do begin result.Error := SysErrorMessage(GetLastError); result.InstanceCount := -1; end; end; Gruß |
Re: WMI Threads 10 Stück fehler 5 ok.
keiner ne idee?
|
Re: WMI Threads 10 Stück fehler 5 ok.
Hallo,
ich weiß nur von einem eigenen Dienst, der über WMI Systeminformationen unserer Server abruft, dass es da ab und an Probleme gibt, die ich bisher nicht habe finden/lösen können. Daher bin ich hergegangen und habe aus dem Dienst ein Batchprogramm gemacht, dass per Taskplaner regelmäßig gestartet wird, dann ist es nicht so schlimm, wenn es ab und an mal abraucht. Ist natürlich keine gute Lösung, aber nach ca. 1 Jahr Fehlersuche, fiel mir da nichts besseres ein. Im ProcessExplorer von SysInternals konnte ich nur beobachten, das die Zahl der genutzten Handles kontinuierlich stieg, bis irgendwann "Schicht" war. Eine wie auch immer geartete Systematik konnte ich nicht finden. Befürchte, dass Dir das jetzt auch nicht wirklich weiter hilft. |
Re: WMI Threads 10 Stück fehler 5 ok.
Hi
Delphi-Quellcode:
Wo wird fWhere übergeben?
...
ObjSet := Services.ExecQuery('SELECT * FROM '+wmiClass+fWhere, ... |
Re: WMI Threads 10 Stück fehler 5 ok.
Na super ich hoffe aber das ich den Fehler finden werde, sonst muss ich mir ne andere Methode einfallen lassen. Hmmmm.
In einer Extra Methode vom Thread. Kann ich aber eigentlich wieder raus nehmen, weil bei einigen Abfragen konnte man noch mit SELECT * FROM x WHERE y abfragen, was aber nicht so ganz funktioniert hat. |
Re: WMI Threads 10 Stück fehler 5 ok.
Warum übergibst du im Konstruktor des Threads eine Methode von deinem Formular? Wie synchronisierst du die Threads mit dem Formular? Wenn man die Klasse TThread benutzt, muss man dazu die Methode Synchronize benutzen.
|
Re: WMI Threads 10 Stück fehler 5 ok.
Mache es mit TCriticalSection.
Sperre wenn ein Thread drauf zugreift und wenn er fertig ist, wieder freigeben. Und die Methode, weil ich die Daten in der Main brauche und der Thread die Daten ja irgend wie übergeben muss. |
Re: WMI Threads 10 Stück fehler 5 ok.
Zitat:
|
Re: WMI Threads 10 Stück fehler 5 ok.
|
Re: WMI Threads 10 Stück fehler 5 ok.
ok es lag am Synchronize. Hätte ich nicht gedacht,
weil bei 5 oder 7 Threads hat es ja funktioniert. Thx |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:51 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-2025 by Thomas Breitkreuz