【问题标题】:C# Using GetProcessIoCounters to read total Disk IO per second (near realtime)C# 使用 GetProcessIoCounters 每秒读取总磁盘 IO(接近实时)
【发布时间】:2021-05-18 04:29:02
【问题描述】:

我一直在谷歌上搜索并阅读各种帖子、解决方案等;但我无法找到或弄清楚如何实现我想要的。

长话短说,我需要显示每个进程每秒的总磁盘 IO 读取 + 写入。为此,我发现 GetProcessIoCounters() 应该可以解决问题。

问题是计算数据并相应地显示。

定义如下:

[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool GetProcessIoCounters(IntPtr hProcess, out IO_COUNTERS lpIoCounters);

[StructLayout(LayoutKind.Sequential)]
public struct IO_COUNTERS
{
    public UInt64 ReadOperationCount;
    public UInt64 WriteOperationCount;
    public UInt64 OtherOperationCount;
    public UInt64 ReadTransferCount;
    public UInt64 WriteTransferCount;
    public UInt64 OtherTransferCount;
};

每秒检索和更新数据:

NativeFunctions.IO_COUNTERS lpIo = new NativeFunctions.IO_COUNTERS();

if (NativeFunctions.GetProcessIoCounters(ProcessList.ProcessData.Handle, out lpIo))
{
   ProcessList.io = lpIo;
}

在这个操作之后,我需要能够说:“I/O Total: X/s”。为此,我正在考虑类似的事情:

ulong total = ProcessList.io.ReadOperationCount + ProcessList.io.WriteOperationCount + ProcessList.io.OtherOperationCount;
total *= 1024;
total /= 1;

但结果并不如预期。我需要查看当前使用的总 I/O,而不是自进程启动以来的总 I/O。

你能指出我正确的方向吗?

感谢您的帮助。

【问题讨论】:

  • 您错误地识别了您的需求。您不需要当前的 I/O 读数。您需要一个时间间隔内的总 I/O。如果您有一个全局累加器,您可以通过从当前累积读数中减去 t0 处的读数来获得一个间隔内的增量。
  • @IInspectable 你说得有道理。你能在这里发布一个 C# noob 的示例吗?
  • @NorbertBoros,IInspectable 表示你可以调用GetProcessIoCounters 两次,使用第 2 次 - 第 1 次,然后除以经过的时间。
  • @DrakeWu-MSFT 你能发布答案吗?同样,这里是 C# 菜鸟。到目前为止,我只使用过 C/C++,但我发现 C#“管理得过于繁琐”。

标签: c# .net winapi


【解决方案1】:
        IntPtr hProcess = GetCurrentProcess();
        IO_COUNTERS lpIo1 = new IO_COUNTERS();
        IO_COUNTERS lpIo2 = new IO_COUNTERS();
        GetProcessIoCounters(hProcess, out lpIo1);

        int Sec = 1;
        Thread.Sleep(Sec * 1000);
        
        GetProcessIoCounters(hProcess, out lpIo2);

        ulong total1 = lpIo1.ReadOperationCount + lpIo1.WriteOperationCount + lpIo1.OtherOperationCount;
        ulong total2 = lpIo2.ReadOperationCount + lpIo2.WriteOperationCount + lpIo2.OtherOperationCount;
        ulong total = (total2 - total1) / Convert.ToUInt64(Sec);

Sec 是两个GetProcessIoCounters 之间的间隔时间。我用Thread.Sleep(Sec * 1000)来模拟Sec秒的经过。

【讨论】:

  • 像魅力一样工作!
猜你喜欢
  • 1970-01-01
  • 2015-12-18
  • 2010-09-07
  • 2013-11-21
  • 2011-09-06
  • 1970-01-01
  • 1970-01-01
  • 2014-11-29
  • 2019-12-12
相关资源
最近更新 更多