1

I'm trying to get the current utilization of my GPU using openhardwaremonitor I've used SensorType.Load to get the utilization of the CPU but for the GPU it is instead returning the memory usage. I'm not sure exactly what to do

if (hardware.HardwareType == HardwareType.GpuNvidia)
{
    hardware.Update();
    foreach (var sensors in hardware.Sensors)
    {
        if (sensors.SensorType == SensorType.Load)
        {
            tester.Text = sensors.Name + ": " + sensors.Value.GetValueOrDefault();
            int gpuLoadInt = Convert.ToInt32(sensors.Value.GetValueOrDefault());
            string gpuLoadString = Convert.ToString(Decimal.Round(gpuLoadInt));
            gpuLoadGuage.Value = gpuLoadInt;
            gpuLoadLabel.Text = gpuLoadString + "%";
        }
    }
}
julianstark999
  • 3,450
  • 1
  • 27
  • 41
Blake
  • 33
  • 4
  • The available documentation for OpenHardwareMonitor is IMO terrible. All I could find was a PDF apparently created in 2010. But could you try to use `SensorType.Level`? Apparently it is different from Load – MindSwipe Jun 19 '20 at 05:40
  • You're absolutely right, the documentation is pretty much non-existent other than the source. Using .level returns no info sadly – Blake Jun 19 '20 at 06:05
  • You could bodge something together using the current clock, and the max clock. The sensor has a property for `Max`, but that is only the max frequency the GPU has reached during monitoring, not the theoretical max. You could use that and save it to disk as well and always use the highest number. This would make your calculated `Load` percentage less accurate at the start, but more and more accurate over time as the user pushes their GPU – MindSwipe Jun 19 '20 at 06:16

1 Answers1

0

The library is a little tricky but once you know a little about it the rest will come out little by little. I did something like this...

    using OpenHardwareMonitor.Hardware; // Don't forget this
    public partial class MainWindow : Window, IVisitor // Don't forget to include the interface
    {    
      // we need to call the method every X seconds to get data
      readonly System.Windows.Threading.DispatcherTimer dispatcherTimer = new 
      System.Windows.Threading.DispatcherTimer();
    }
    public MainWindow()
    {
      dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
      dispatcherTimer.Interval = new TimeSpan(0, 0, 2); // <= two seconds
    }

    public void VisitComputer(IComputer computer) => computer.Traverse(this);
    public void VisitHardware(IHardware hardware)
    {
     hardware.Update();
     foreach (IHardware subHardware in hardware.SubHardware) subHardware.Accept(this);
    }
    public void VisitSensor(ISensor sensor) { }
    public void VisitParameter(IParameter parameter) { }
    
    private void dispatcherTimer_Tick(object sender, EventArgs e)
    {
      Thread ThreadGpu = new Thread(() => GetGpuInfo());
      ThreadGpu.Start();
    }

    GetGpuInfo()
    {
      Computer computer = new Computer();
      UpdateVisitor updateVisitor = new UpdateVisitor();
       try
       {
        computer.Open(); // You must initialize what you are going to use
        computer.GPUEnabled = true; // You must initialize what you are going to use
        computer.Accept(updateVisitor); // You NEED this line to update

        if (computer.Hardware.Length > 0)
        {
          foreach (var item in computer.Hardware)
          {
            foreach (ISensor gpu in item.Sensors)
            {
              if (gpu.Name == "GPU Memory" && gpu.Index == 1)
                Console.WriteLine("Memory:" + Math.Round((float)gpu.Value) + "Mhz");
              if (gpu.SensorType == SensorType.Temperature)
                Console.WriteLine("Temperature:" + Math.Round((float)gpu.Value) + "°C");
              if (gpu.SensorType == SensorType.Load && gpu.Name == "GPU Core")
                Console.WriteLine("GPU Core:" + gpu.Value);
              if (gpu.SensorType == SensorType.Clock && gpu.Name == "GPU Core")
                Console.WriteLine(gpu.Value + "Mhz");
            }
          }
        }
       }
       catch (Exception ex)
       {
         Console.WriteLine(ex.Message);
       }
       computer.Close(); // Close resources
     }

You must use this OpenHardwareMonitor class as well, otherwise the data is not updated. You can use it in the same namespace or in another classes file

public class UpdateVisitor : IVisitor
  {
    public void VisitComputer(IComputer computer)
    {
      try
      {
        computer.Traverse(this);
      }
      catch (Exception ex)
      {
        Console.WriteLine(ex.Message);
      }
    }

    public void VisitHardware(IHardware hardware)
    {
      try
      {
        hardware.Update();
        foreach (IHardware subHardware in hardware.SubHardware)
          subHardware.Accept(this);
      }
      catch (Exception ex)
      {
        Console.WriteLine(ex.Message);
      }
    }

    public void VisitSensor(ISensor sensor) { }

    public void VisitParameter(IParameter parameter) { }
  }
}

I'm still learning C# but hope this help

Nando
  • 1
  • To repeatedly get sensor data, is it better to create Computer and UpdateVisitor objects at class level? I'm wondering whether its better in terms of performance – tunafish24 Feb 27 '21 at 12:30