Windows runtime WinRT应用程序有没有办法测量自己的CPU使用率?

Windows runtime WinRT应用程序有没有办法测量自己的CPU使用率?,windows-runtime,cpu-usage,Windows Runtime,Cpu Usage,我正在尝试用不同的方法在WinRT中制作游戏图形,如果我的测试应用程序能够测量并显示自己的CPU使用情况,那就太好了,这样我就可以比较不同的方法(ItemsControl与手动移动图像与DirectX) 在成熟的.NET中,我可以在两个已知的时间点读取数据,然后将增量处理器时间除以增量时间(如果需要,可以根据处理器数量进行调整)。如果应用程序在完全信任的情况下运行,我甚至可以找到它的进程实例(因为它完成了将GUI放到屏幕上的所有繁重工作),并将其添加到我的CPU时间中。这是我在我的WinForm

我正在尝试用不同的方法在WinRT中制作游戏图形,如果我的测试应用程序能够测量并显示自己的CPU使用情况,那就太好了,这样我就可以比较不同的方法(ItemsControl与手动移动图像与DirectX)

在成熟的.NET中,我可以在两个已知的时间点读取数据,然后将增量处理器时间除以增量时间(如果需要,可以根据处理器数量进行调整)。如果应用程序在完全信任的情况下运行,我甚至可以找到它的进程实例(因为它完成了将GUI放到屏幕上的所有繁重工作),并将其添加到我的CPU时间中。这是我在我的WinForms和WPF版本中采用的方法

但在WinRT中,System.Diagnostics.Process类不存在。如果有替代API,我不确定在哪里可以找到它

我可以打开任务管理器,将其设置为保持在顶部,并在我的应用程序运行时密切关注它。这不太理想,因为(a)它覆盖了我窗口的一部分,因此可能会稍微扭曲结果;(b)我自己无法对结果进行任何汇总或记录(例如,“这里是十秒钟内的平均CPU使用情况”)。因此,如果有某种方法可以通过编程获得CPU使用率,我更愿意这样做,因为它给了我更多的灵活性


WinRT应用程序是否有办法确定自己的CPU使用量?

不幸的是,WinRT中没有与System.Diagnostics.Process类等效的类,至少当前没有(和)。一些本机API已向WinRT公开(请参见示例),但我找不到列表。

不幸的是,WinRT中没有与System.Diagnostics.Process类等效的类,至少当前没有(和)。一些本机API暴露于WinRT(请参见示例),但我找不到列表。

我不知道有任何“批准”的API可以从Windows应用商店应用程序中获取此信息

但是,如果您只想在测试应用程序中执行此操作,则可以使用“未经批准”的API。如果您使用未经批准的API,您的程序将无法通过WACK认证,并且无法上载到应用商店,但对于本地测试来说,这是可以的。请注意,当您调用未经批准的API时,没有任何保证,因此行为在形式上是未定义的,但许多函数都可以正常工作——至少在当前版本中是这样

我在今年夏天早些时候写的一篇文章中演示了如何调用
allocsole
。您可以使用类似于C++的类似方法,既可以使用p/INVIKE调用本地函数,也可以编写一个C++窗口运行时组件,它可以从Cy.[/P>]调用。 对于您的场景,我建议调用以获取当前进程的句柄,并将其传递给获取用户和内核时间。我运行了一个简短的测试,通过这种方法得到了合理的结果

下面是一个完整的C#类,它使用p/Invoke进行调用:

static class DebugProcessTimes
{
    [StructLayout(LayoutKind.Sequential)]
    private struct FileTime
    {
        public UInt32 Low;
        public UInt32 High;
    }

    private static UInt64 ToUInt64(FileTime time)
    {
        return ((UInt64)time.High << 32) + time.Low;
    }

    [DllImport("kernel32.dll")]
    private static extern IntPtr GetCurrentProcess();

    [DllImport("kernel32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool GetProcessTimes(
        IntPtr hProcess,
        out FileTime lpCreationTime,
        out FileTime lpExitTime,
        out FileTime lpKernelTime,
        out FileTime lpUserTime);

    public struct ProcessTimes
    {
        public UInt64 CreationTime;
        public UInt64 ExitTime;
        public UInt64 KernelTime;
        public UInt64 UserTime;
    }

    public static ProcessTimes GetProcessTimes()
    {
        FileTime creation, exit, kernel, user;

        if (!GetProcessTimes(GetCurrentProcess(),
                out creation, out exit, out kernel, out user))
            throw new Exception(":'(");

        return new ProcessTimes
        {
            CreationTime = ToUInt64(creation),
            ExitTime     = ToUInt64(exit),
            KernelTime   = ToUInt64(kernel),
            UserTime     = ToUInt64(user)
        };
    }
}
我不知道有任何“批准”的API可以从Windows应用商店应用程序中获取此信息

但是,如果您只想在测试应用程序中执行此操作,则可以使用“未经批准”的API。如果您使用未经批准的API,您的程序将无法通过WACK认证,并且无法上载到应用商店,但对于本地测试来说,这是可以的。请注意,当您调用未经批准的API时,没有任何保证,因此行为在形式上是未定义的,但许多函数都可以正常工作——至少在当前版本中是这样

我在今年夏天早些时候写的一篇文章中演示了如何调用
allocsole
。您可以使用类似于C++的类似方法,既可以使用p/INVIKE调用本地函数,也可以编写一个C++窗口运行时组件,它可以从Cy.[/P>]调用。 对于您的场景,我建议调用以获取当前进程的句柄,并将其传递给获取用户和内核时间。我运行了一个简短的测试,通过这种方法得到了合理的结果

下面是一个完整的C#类,它使用p/Invoke进行调用:

static class DebugProcessTimes
{
    [StructLayout(LayoutKind.Sequential)]
    private struct FileTime
    {
        public UInt32 Low;
        public UInt32 High;
    }

    private static UInt64 ToUInt64(FileTime time)
    {
        return ((UInt64)time.High << 32) + time.Low;
    }

    [DllImport("kernel32.dll")]
    private static extern IntPtr GetCurrentProcess();

    [DllImport("kernel32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool GetProcessTimes(
        IntPtr hProcess,
        out FileTime lpCreationTime,
        out FileTime lpExitTime,
        out FileTime lpKernelTime,
        out FileTime lpUserTime);

    public struct ProcessTimes
    {
        public UInt64 CreationTime;
        public UInt64 ExitTime;
        public UInt64 KernelTime;
        public UInt64 UserTime;
    }

    public static ProcessTimes GetProcessTimes()
    {
        FileTime creation, exit, kernel, user;

        if (!GetProcessTimes(GetCurrentProcess(),
                out creation, out exit, out kernel, out user))
            throw new Exception(":'(");

        return new ProcessTimes
        {
            CreationTime = ToUInt64(creation),
            ExitTime     = ToUInt64(exit),
            KernelTime   = ToUInt64(kernel),
            UserTime     = ToUInt64(user)
        };
    }
}

有趣!由于pinvoke.net上的声明依赖于WinRT中未公开的System.Runtime.InteropServices.FILETIME等类型,您是否介意发布您的P/Invoke代码,因为听起来您已经把它弄明白了?我没有编写P/Invoke代码,但我尝试了一下。请参阅更新。结果看起来合理。有趣!由于pinvoke.net上的声明依赖于WinRT中未公开的System.Runtime.InteropServices.FILETIME等类型,您是否介意发布您的P/Invoke代码,因为听起来您已经把它弄明白了?我没有编写P/Invoke代码,但我尝试了一下。请参阅更新。结果看起来是合理的。