diff --git a/LibreHardwareMonitorLib/Hardware/Network/Network.cs b/LibreHardwareMonitorLib/Hardware/Network/Network.cs index 671e132..b5df621 100644 --- a/LibreHardwareMonitorLib/Hardware/Network/Network.cs +++ b/LibreHardwareMonitorLib/Hardware/Network/Network.cs @@ -44,53 +44,71 @@ namespace LibreHardwareMonitor.Hardware.Network get { return HardwareType.Network; } } - internal NetworkInterface NetworkInterface { get; } + internal NetworkInterface NetworkInterface { get; private set; } public override void Update() { - long newTick = Stopwatch.GetTimestamp(); - double dt = new TimeSpan(newTick - _lastTick).TotalSeconds; - - IPv4InterfaceStatistics interfaceStats = NetworkInterface.GetIPv4Statistics(); - - // Report out the number of GB (2^30 Bytes) that this interface has up/downloaded. Note - // that these values can reset back at zero (eg: after waking from sleep). - _dataUploaded.Value = (float)(interfaceStats.BytesSent / (double)0x40000000); - _dataDownloaded.Value = (float)(interfaceStats.BytesReceived / (double)0x40000000); - - // Detect a reset in interface stats if the new total is less than what was previously - // seen. While setting the previous values to zero doesn't encapsulate the value the - // instant before the reset, it is the best approximation we have. - if (interfaceStats.BytesSent < _bytesUploaded || interfaceStats.BytesReceived < _bytesDownloaded) + try { - _bytesUploaded = 0; - _bytesDownloaded = 0; + if (NetworkInterface == null) + return; + + + long newTick = Stopwatch.GetTimestamp(); + double dt = new TimeSpan(newTick - _lastTick).TotalSeconds; + + IPv4InterfaceStatistics interfaceStats = NetworkInterface.GetIPv4Statistics(); + + // Report out the number of GB (2^30 Bytes) that this interface has up/downloaded. Note + // that these values can reset back at zero (eg: after waking from sleep). + _dataUploaded.Value = (float)(interfaceStats.BytesSent / (double)0x40000000); + _dataDownloaded.Value = (float)(interfaceStats.BytesReceived / (double)0x40000000); + + // Detect a reset in interface stats if the new total is less than what was previously + // seen. While setting the previous values to zero doesn't encapsulate the value the + // instant before the reset, it is the best approximation we have. + if (interfaceStats.BytesSent < _bytesUploaded || interfaceStats.BytesReceived < _bytesDownloaded) + { + _bytesUploaded = 0; + _bytesDownloaded = 0; + } + + long dBytesUploaded = interfaceStats.BytesSent - _bytesUploaded; + long dBytesDownloaded = interfaceStats.BytesReceived - _bytesDownloaded; + + // Upload and download speeds are reported as the number of bytes transfered over the + // time difference since the last report. In this way, the values represent the average + // number of bytes up/downloaded in a second. + _uploadSpeed.Value = (float)(dBytesUploaded / dt); + _downloadSpeed.Value = (float)(dBytesDownloaded / dt); + + // Network speed is in bits per second, so when calculating the load on the NIC we first + // grab the total number of bits up/downloaded + long dbits = (dBytesUploaded + dBytesDownloaded) * 8; + + // Converts the ratio of total bits transferred over time over theoretical max bits + // transfer rate into a percentage load + double load = (dbits / dt / NetworkInterface.Speed) * 100; + + // Finally clamp the value between 0% and 100% to avoid reporting nonsensical numbers + _networkUtilization.Value = (float)Math.Min(Math.Max(load, 0), 100); + + // Store the recorded values and time, so they can be used in the next update + _bytesUploaded = interfaceStats.BytesSent; + _bytesDownloaded = interfaceStats.BytesReceived; + _lastTick = newTick; + } + catch (NetworkInformationException networkInformationException) when (unchecked(networkInformationException.NativeErrorCode == (int)0x80004005)) + { + foreach (NetworkInterface networkInterface in NetworkInterface.GetAllNetworkInterfaces()) + { + if (networkInterface.Id.Equals(NetworkInterface?.Id)) + { + NetworkInterface = networkInterface; + break; + } + } } - - long dBytesUploaded = interfaceStats.BytesSent - _bytesUploaded; - long dBytesDownloaded = interfaceStats.BytesReceived - _bytesDownloaded; - - // Upload and download speeds are reported as the number of bytes transfered over the - // time difference since the last report. In this way, the values represent the average - // number of bytes up/downloaded in a second. - _uploadSpeed.Value = (float)(dBytesUploaded / dt); - _downloadSpeed.Value = (float)(dBytesDownloaded / dt); - - // Network speed is in bits per second, so when calculating the load on the NIC we first - // grab the total number of bits up/downloaded - long dbits = (dBytesUploaded + dBytesDownloaded) * 8; - - // Converts the ratio of total bits transferred over time over theoretical max bits - // transfer rate into a percentage load - double load = (dbits / dt / NetworkInterface.Speed) * 100; - - // Finally clamp the value between 0% and 100% to avoid reporting nonsensical numbers - _networkUtilization.Value = (float)Math.Min(Math.Max(load, 0), 100); - - // Store the recorded values and time, so they can be used in the next update - _bytesUploaded = interfaceStats.BytesSent; - _bytesDownloaded = interfaceStats.BytesReceived; - _lastTick = newTick; } } } diff --git a/LibreHardwareMonitorLib/Hardware/Network/NetworkGroup.cs b/LibreHardwareMonitorLib/Hardware/Network/NetworkGroup.cs index 9fae653..03a8935 100644 --- a/LibreHardwareMonitorLib/Hardware/Network/NetworkGroup.cs +++ b/LibreHardwareMonitorLib/Hardware/Network/NetworkGroup.cs @@ -21,6 +21,7 @@ namespace LibreHardwareMonitor.Hardware.Network { _settings = settings; AddNetworkInterfaces(settings); + NetworkChange.NetworkAddressChanged += NetworkChange_NetworkAddressChanged; NetworkChange.NetworkAvailabilityChanged += NetworkChange_NetworkAddressChanged; } @@ -54,6 +55,7 @@ namespace LibreHardwareMonitor.Hardware.Network { NetworkChange.NetworkAddressChanged -= NetworkChange_NetworkAddressChanged; NetworkChange.NetworkAvailabilityChanged -= NetworkChange_NetworkAddressChanged; + foreach (var nic in _hardware) nic.Close(); }