Laden...

Problem mit PerformanceCounter beim CPU-Last auslesen

Erstellt von ddr2 vor 13 Jahren Letzter Beitrag vor 13 Jahren 3.561 Views
D
ddr2 Themenstarter:in
5 Beiträge seit 2010
vor 13 Jahren
Problem mit PerformanceCounter beim CPU-Last auslesen

Hi Community,

ich arbeite zur Zeit an einem Projekt, in welchem es darum geht, die CPU-Last und den RAM-Verbrauch von Prozessen zu ermitteln. Die ganze Arbeit soll mit PerformanceCounter programmiert werden. Das klappt auch soweit schon ganz gut, nur habe ich noch folgendes Problem:

Einige Programme (z.B. Internet Explorer) haben immer mehrere Prozesse laufen. Der IE startet z.B. für jeden neuen Tab einen eigenen Prozess. Ich möchte in solchen Fällen die CPU-Last und den RAM-Verbrauch aller gleichen Prozesse addieren und mir dann ausgeben lassen. Nun zu meinem eigentlichen Problem: Meine Idee war es mir alle Prozesse mit dem gleichen Namen (z.B. iexplore.exe) in einem Array zu speichern und anschließend für jeden Prozess CPU-Last und RAM-Verbrauch auslesen. Das Problem ist allerdings, dass der Performance Counter natürlich immer den selben Prozess ausliest, also sozusagen den ersten den er findeet unter dem Namen (z.B. iexplore.exe). Es können also 10 gleiche Prozesse gestartet sein, es wird aber immer nur CPU-Last und RAM-Verbrauch eines Prozesses ausgelesen.

Hat irgendeiner von euch eine Idee, wie ich dieses Problem lösen kann? Gibt es vielleicht eine Möglichkeit dem PerformanceCounter eine Prozess-ID zu übergeben? Oder gibt es vll eine gute Alternative zu PerformanceCountern?? Habe noch nichts brauchbares im Netz gefunden...

Viele Grüße
ddr

S
248 Beiträge seit 2008
vor 13 Jahren

Hallo ddr2,

ich habe für ein Projekt zum Messen von CPU Zeit die Win32-Klasse Win32_PerfFormattedData_PerfProc_Process verwendet.
Dort kannst du die Process-IDs und auch den Parent-Prozess auslesen, jedoch musst du die CPU-Zeiten wohl manuell berechnen.

Für die Verwendung musst du einen Verweis auf System.Management hinzufügen.

            ManagementObjectSearcher searcher = new ManagementObjectSearcher(
                @"Select Name, PercentProcessorTime, IDProcess, CreatingProcessID from Win32_PerfRawData_PerfProc_Process");

            foreach (var obj in searcher.Get())
            {
                Console.WriteLine("{0} {1} {2} {3}", obj["Name"], obj["PercentProcessorTime"], obj["IDProcess"], obj["CreatingProcessID"]);
            }   

Vielleicht hilft dir das weiter.

Grüße,
spooky

D
ddr2 Themenstarter:in
5 Beiträge seit 2010
vor 13 Jahren

Hey,

sorry dass ich jetzt erst zurückschreibe.. Ging vorher leider nicht...

dankeschön für den Tipp. Leider komme ich auch hier nicht weiter. Wie kann ich aus den Werten, die ich für die Prozessorzeit bekomme die CPU-Last berechnen??

Viele Grüße
ddr2

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo ddr2,

PercentProcessorTime ist doch schon die CPU- (bzw. Kern-)Last.

herbivore

D
ddr2 Themenstarter:in
5 Beiträge seit 2010
vor 13 Jahren

Hey,

ich weis nicht, ich bekomme da für den Firefox z.B. die Zahl 188649472 raus.. ich vermute dann dass ich diese zahl vll irgendwie umrechnen muss... aber wie??
😦

S
248 Beiträge seit 2008
vor 13 Jahren

Hi,

du kannst die CPU-Zeit nur berechnen indem du diese innerhalb einer Zeitspanne betrachtest, alle 1000ms über ein Event zB. Dabei brauchst du "PercentProcessorTime" und "TimeStamp_Sys100NS", wobei die Formel
(cpu2-cpu1)/(time2-time1) ist.

In dem Beispiel wird das noch mit 100 multipliziert. Das Ganze muss man, so vermute ich, noch durch die Anzahl der CPU-Kerne dividieren (Environment.ProcessorCount); zumindest waren die Werte dann plausibel.

spooky

2.891 Beiträge seit 2004
vor 13 Jahren

Das Problem ist allerdings, dass der Performance Counter natürlich immer den selben Prozess ausliest, also sozusagen den ersten den er findeet unter dem Namen (z.B. iexplore.exe). Es können also 10 gleiche Prozesse gestartet sein, es wird aber immer nur CPU-Last und RAM-Verbrauch eines Prozesses ausgelesen

Du kannst die Performance Counter verschiedener Instanzen des gleichen Prozesses über die PerformanceCounter.InstanceName-Eigenschaft (System.Diagnostics) auslesen.
Die erste gestartete Instanz hat den normalen Prozessnamen (z.B. "iexplore"). Die danach folgenden Prozesse werden dann folgendermaßen durchnummeriert: Zweite Instanz "iexplore#1", dritte Instanz "iexplore#2" etc.

Unter c# - How to get parent process in .NET in managed way - Stack Overflow solltest du auch eine Möglichkeit finden, eine ProcessID auf den Indexnamen abzubilden (und andersrum).

Gruß,
dN!3L

D
ddr2 Themenstarter:in
5 Beiträge seit 2010
vor 13 Jahren

Hey,

super Leute, vielen Dank für die vielen Ideen... 😃 ich denke jetzt läuft mein Programm soweit.. wird heut direkt dem Professor vorgestellt 😉

Viele Grüße

D
ddr2 Themenstarter:in
5 Beiträge seit 2010
vor 13 Jahren

Hey,

wollte mein Programm jetzt folgendermaßen umstellen. Zu Beginn erstelle ich für jeden Prozess der überwacht werden soll einen PerformanceCounter und speichere diesen in einer PerformanceCounter-Liste. Anschließend sollen alle 2 Sekunden (durch nen Timer) mit Hilfe dieser Liste die Prozessdaten der einzelnen Prozesse abgeruft werden. Das geht im ersten durchlauf auch einwandfrei, im zweite erhalte ich aber für die CPU-Auslastung unrealistische Werte jenseits von 200.000...

Vorher hatte ich das Programm folgendermaßen: Anstatt die PerformanceCounter-Liste nur einmal zu erstellen, habe ich sie bei jedem Timerdurchlauf nach Auslesen der Daten leer gemacht und für den nächsten Durchlauf neu erstellt. In diesem Fall trat das Problem mit den unrealistischen CPU-Daten nicht auf..

Jemand eine Idee? 😃

Ansonsten allen frohe Weihnachten 😃

ddr2