@@ -96,12 +96,16 @@ public class OSUtility
96
96
public static bool UsesYumPackageManager { get ; private set ; }
97
97
98
98
private static readonly string tempFolder ;
99
+ private static readonly object locker = new ( ) ;
100
+
101
+ private static PerformanceCounter windowsCpuCounter ;
102
+ private static float windowsCpuUsage ;
103
+ private static float networkUsage = - 1.0f ;
99
104
100
105
private static bool isWindows ;
101
106
private static bool isLinux ;
102
107
private static bool isMac ;
103
108
104
-
105
109
private static readonly string processVerb ;
106
110
107
111
static OSUtility ( )
@@ -473,13 +477,37 @@ public static bool GetCpuUsage(out float percentUsed)
473
477
percentUsed = 0.0f ;
474
478
if ( isWindows )
475
479
{
476
- string output = StartProcessAndWait ( 60000 , "wmic" , "cpu get loadpercentage" , out _ , LogLevel . Trace ) ;
477
- string [ ] lines = output . Split ( '\n ' , StringSplitOptions . RemoveEmptyEntries | StringSplitOptions . TrimEntries ) ;
478
- if ( lines . Length > 1 && float . TryParse ( lines [ ^ 1 ] , NumberStyles . None , CultureInfo . InvariantCulture , out percentUsed ) )
480
+ if ( windowsCpuCounter is null )
479
481
{
480
- percentUsed *= 0.01f ;
481
- return true ;
482
+ lock ( locker )
483
+ {
484
+ if ( windowsCpuCounter is null )
485
+ {
486
+ windowsCpuCounter = new PerformanceCounter ( "Processor Information" , "% Processor Utility" , "_Total" ) ;
487
+
488
+ // capture windows cpu in background
489
+ System . Threading . Tasks . Task . Run ( async ( ) =>
490
+ {
491
+ windowsCpuUsage = Math . Clamp ( windowsCpuCounter . NextValue ( ) * 0.01f , 0.0f , 1.0f ) ;
492
+ while ( ! Environment . HasShutdownStarted )
493
+ {
494
+ await System . Threading . Tasks . Task . Delay ( 1000 ) ;
495
+ windowsCpuUsage = Math . Clamp ( windowsCpuCounter . NextValue ( ) * 0.01f , 0.0f , 1.0f ) ;
496
+ }
497
+ } ) ;
498
+ }
499
+ }
482
500
}
501
+
502
+ percentUsed = windowsCpuUsage ;
503
+ //string output = StartProcessAndWait(60000, "wmic", "cpu get loadpercentage", out _, LogLevel.Trace);
504
+ //string[] lines = output.Split('\n', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
505
+ //if (lines.Length > 1 && float.TryParse(lines[^1], NumberStyles.None, CultureInfo.InvariantCulture, out percentUsed))
506
+ //{
507
+ //percentUsed *= 0.01f;
508
+ //return true;
509
+ //}
510
+ return true ;
483
511
}
484
512
else if ( isLinux )
485
513
{
@@ -493,7 +521,7 @@ public static bool GetCpuUsage(out float percentUsed)
493
521
string piece = lines [ ^ 1 ] [ pos ..] . Trim ( ) ;
494
522
if ( pos > 0 && float . TryParse ( piece , NumberStyles . AllowDecimalPoint , CultureInfo . InvariantCulture , out percentUsed ) )
495
523
{
496
- percentUsed = 1.0f - ( 0.01f * percentUsed ) ;
524
+ percentUsed = Math . Clamp ( 1.0f - ( 0.01f * percentUsed ) , 0.0f , 1.0f ) ;
497
525
return true ;
498
526
}
499
527
}
@@ -502,6 +530,68 @@ public static bool GetCpuUsage(out float percentUsed)
502
530
return false ;
503
531
}
504
532
533
+ /// <summary>
534
+ /// Get system network usage
535
+ /// </summary>
536
+ /// <param name="percentUsed">Percent of system network used, 0-1</param>
537
+ /// <returns>True if network usage could be determined, false otherwise</returns>
538
+ public static bool GetNetworkUsage ( out float percentUsed )
539
+ {
540
+ if ( networkUsage < 0.0f )
541
+ {
542
+ lock ( locker )
543
+ {
544
+ if ( networkUsage < 0.0f )
545
+ {
546
+ networkUsage = 0.0f ;
547
+
548
+ // capture network usage in background
549
+ System . Threading . Tasks . Task . Run ( async ( ) =>
550
+ {
551
+ System . Net . NetworkInformation . NetworkInterface [ ] nics = null ;
552
+ long [ ] prevTransfer = null ;
553
+ double [ ] maxSpeeds = null ;
554
+ while ( ! Environment . HasShutdownStarted )
555
+ {
556
+ if ( nics is null )
557
+ {
558
+ try
559
+ {
560
+ nics = System . Net . NetworkInformation . NetworkInterface . GetAllNetworkInterfaces ( ) . Where ( n => n . NetworkInterfaceType == System . Net . NetworkInformation . NetworkInterfaceType . Ethernet ) . ToArray ( ) ;
561
+ prevTransfer = new long [ nics . Length ] ;
562
+ maxSpeeds = new double [ nics . Length ] ;
563
+ for ( int i = 0 ; i < nics . Length ; i ++ )
564
+ {
565
+ prevTransfer [ i ] = nics [ i ] . GetIPStatistics ( ) . BytesReceived + nics [ i ] . GetIPStatistics ( ) . BytesSent ;
566
+ maxSpeeds [ i ] = ( double ) ( nics [ i ] . Speed / 8 ) ;
567
+ }
568
+ }
569
+ catch
570
+ {
571
+ // non-fatal, try again later
572
+ }
573
+ }
574
+ await System . Threading . Tasks . Task . Delay ( 1000 ) ;
575
+ if ( nics is not null )
576
+ {
577
+ float percent = 0.0f ;
578
+ for ( int i = 0 ; i < nics . Length ; i ++ )
579
+ {
580
+ long currentTransfer = nics [ i ] . GetIPStatistics ( ) . BytesReceived + nics [ i ] . GetIPStatistics ( ) . BytesSent ;
581
+ percent = ( float ) Math . Max ( percent , ( double ) ( currentTransfer - prevTransfer [ i ] ) / maxSpeeds [ i ] ) ;
582
+ prevTransfer [ i ] = currentTransfer ;
583
+ }
584
+ networkUsage = Math . Clamp ( percent , 0.0f , 1.0f ) ;
585
+ }
586
+ }
587
+ } ) ;
588
+ }
589
+ }
590
+ }
591
+ percentUsed = networkUsage ;
592
+ return true ;
593
+ }
594
+
505
595
/// <summary>
506
596
/// Easy way to execute processes. If the process has not finished after 60 seconds, it is forced killed.
507
597
/// </summary>
0 commit comments