C#: PerformaceCounter vs. WMI

In einem Projekt, welches eine GUI zu einem Windows-Dienst beinhaltet, zeige ich unter anderem die Uptime des Systems an.
Früher noch über des TickCount gedöhns, das dann aber nach 23 tagen oder so auf einmal anfängt ins Negative zu laufen, weil der Int zu kurz ist.
Später dann über den PerformanceCounter.
Kürzlich merkte ich, das genau dieser PerformanceCounter ziemlich langsam ist.
Beim Ersten Aufruf braucht er auf meinem System im Schnitt 1800ms, bedeuet das die GUI da mal 1,8 sek mehr beim starten braucht, was sich sehr unangenehm anfühlt beim starten der GUI.
Nach ein wenig ruhiges und entspanntes Googlen habe ich dann eine Methode gefunden, welche mir auch die Uptime des Systems ausgeben kann, aber über WMI statt den PerformanceCounter zu benutzen.
Beide Möglichkeiten möchte ich jetzt hier aufzeigen.

Zuerst die Methode mit dem PerformanceCounter:

1
2
3
4
5
6
7
8
9
10
11
12
Stopwatch sw = new Stopwatch();
sw.Start();
PerformanceCounter upTime = new PerformanceCounter("System", "System Up Time");
upTime.NextValue();
float upt = upTime.NextValue();
upt = upt / 60;
DateTime dt_laufzeit = DateTime.Now.AddMinutes(-Convert.ToDouble(upt));
DateTime dt_jetzt = DateTime.Now;
TimeSpan ts = dt_jetzt - dt_laufzeit;
Console.WriteLine(ts.ToString()); // 41.09:09:56.7220006
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds); //1864

^^ Die StopWatch sagt, das hierfür 1,864 Sek länger gewartet werden muss – und das bei jedem Starten der GUI.
Vorteil daran ist, das es nur beim ersten aufruf so lang dauert – würde man danach noch mal diese Methode aufrufen, so würde sie nur noch 1ms dauern.

Hier nun die Methode mit der WMI-Abfrage:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Stopwatch sw = new Stopwatch();
sw.Start();
TimeSpan uptimeTs = new TimeSpan();
//management objects to interact with WMI
ManagementClass management = new ManagementClass("Win32_OperatingSystem");
ManagementObjectCollection mngInstance = management.GetInstances();
 
//loop throught the mngInstance
 
DateTime dt_laufzeit = DateTime.Now;
foreach (ManagementObject mngObject in mngInstance)
{
    dt_laufzeit = System.Management.ManagementDateTimeConverter.ToDateTime(mngObject["LastBootUpTime"].ToString());
}
 
DateTime dt_jetzt = DateTime.Now;
TimeSpan ts = dt_jetzt - dt_laufzeit;
Console.WriteLine(ts.ToString()); // 41.09:09:57.1693662
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds); //58

^^ Ist insgesamt etwas mehr Code, schaut auch etwas frickeliger aus – nimmt aber sehr viel weniger Zeit in Anspruch als der PerformanceCounter.
Mit 0,058 sek dauert das starten der GUI nicht mehr so lang.

Also – GUI startet schneller – Ziel wurde erreicht 🙂

leave your comment

*

Unterstütze den Frickelblog!