WinRT应用程序有什么方法可以衡量自己的CPU使用率? [英] Is there any way for a WinRT app to measure its own CPU usage?

查看:92
本文介绍了WinRT应用程序有什么方法可以衡量自己的CPU使用率?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



在完整的.NET中,我可以阅读 Process.TotalProcessorTime 在两个已知时间点,然后将增量处理器时间除以增量时间(如果有处理器数量,则进行调整)必要)。如果应用程序以完全信任的方式运行,我什至可以找到 dwm.exe (因为它完成了将GUI显示在屏幕上的所有繁重工作)并将其添加到我的CPU时间中。这是我在游戏图形测试套件的WinForms和WPF版本中采用的方法。。 p>

但是在WinRT中,System.Diagnostics.Process类不存在。如果还有其他API,我不确定在哪里寻找它。



我可以打开任务管理器并将其设置在最上面,然后保持警惕在我的应用运行时对其进行处理。这不理想,因为(a)它覆盖了我的窗口的一部分,因此可能会使结果稍微偏斜; (b)我无法自行汇总或记录结果(例如这是十秒钟的平均CPU使用率)。因此,如果可以通过编程方式获得CPU使用率的话,我宁愿这样做,只是因为它为我提供了更多的灵活性。



有没有WinRT应用程序确定自己的CPU使用率的方法?

解决方案

我不知道任何批准的 可以从Windows Store应用程序中获取此信息的API。



但是,如果您只想在测试应用程序中执行此操作,则可以使用未经批准的API。如果您使用未经批准的API,则您的程序将不会通过WACK认证,也无法上传到商店,但是可以在本地进行测试。请注意,当您调用未经批准的API时无法保证,因此该行为在形式上是未定义的,但是许多功能可以正常工作-至少在当前版本中如此。



我在今年夏天早些时候写的一篇文章中演示了如何调用 AllocConsole 在Metro风格应用中进行printf调试 。您可以使用P / Invoke调用本机函数,也可以通过编写可以从C#调用的C ++ Windows运行时组件来实现与C#类似的操作。



您的情况下,建议您致电 GetCurrentProcess 以获取当前进程的句柄,并将其传递给 GetProcessTimes 来获取用户和内核时间。我通过这种方法进行了简短的测试,并获得了合理的外观结果。



这是一个完整的C#类,使用P / Invoke进行了调用:

 静态类DebugProcessTimes 
{
[StructLayout(LayoutKind.Sequential)]
私有结构FileTime
{
public UInt32低;
public UInt32高;
}

私有静态UInt64 ToUInt64(FileTime时间)
{
return((UInt64)time.High<< <32)+ time.Low;
}

[DllImport( kernel32.dll)]
私有静态外部IntPtr GetCurrentProcess();

[DllImport( kernel32.dll)]
[返回:MarshalAs(UnmanagedType.Bool)]
私有静态外部布尔GetProcessTimes(
IntPtr hProcess,
出FileTime lpCreationTime,
出FileTime lpExitTime,
出FileTime lpKernelTime,
出FileTime lpUserTime);

公共结构ProcessTimes
{
public UInt64 CreationTime;
public UInt64 ExitTime;
public UInt64 KernelTime;
public UInt64 UserTime;
}

public static ProcessTimes GetProcessTimes()
{
FileTime创建,退出,内核,用户;

if(!GetProcessTimes(GetCurrentProcess(),
退出创建,退出,内核退出,用户退出))
throw new Exception(:'();

返回新的ProcessTimes
{
CreationTime = ToUInt64(creation),
ExitTime = ToUInt64(exit),
KernelTime = ToUInt64(kernel),
UserTime = ToUInt64(user)
};
}
}

用法:

  var times = DebugProcessTimes.GetProcessTimes(); 


I'm experimenting with different ways to do game graphics in WinRT, and it'd be nice if my test app could measure and display its own CPU usage, so I could compare different approaches (ItemsControl vs. manually moving Images around vs. DirectX).

In full-fledged .NET, I can read Process.TotalProcessorTime at two known points in time, and then take the delta processor time divided by the delta time (adjusted for number of processors if necessary). If the app is running in full-trust, I can even find the Process instance for dwm.exe (since it does all the heavy lifting of putting the GUI on the screen) and add that into my CPU time. This is the approach I took in the WinForms and WPF versions of my Game Graphics test suite.

But in WinRT, the System.Diagnostics.Process class does not exist. If there's an alternate API, I'm not sure where to look for it.

I can open Task Manager and set it to stay on top, and just keep an eye on it as my app runs. This is less than ideal, since (a) it covers part of my window, and therefore probably skews the results slightly; and (b) I can't do any of my own aggregation or logging of the results (e.g. "here was the average CPU usage over a ten-second span"). So if there's some way I could get my CPU usage programmatically, I'd prefer that, just because of the added flexibility it gives me.

Is there any way for a WinRT app to determine its own CPU usage?

解决方案

I don't know of any "approved" API to get this information from within a Windows Store app.

However, if you only want to do this in a test app, you can use "unapproved" APIs. If you use an API that is not approved, your program will not pass WACK certification and can't be uploaded to the store, but for testing locally that's okay. Note that there are no guarantees when you call unapproved APIs, so the behavior is formally undefined, but many functions work fine--at least in the current release.

I demonstrated how to call AllocConsole in an article I wrote earlier this summer, "printf debugging in Metro style apps". You can do something similar from C#, either using P/Invoke to call the native function, or by writing a C++ Windows Runtime Component that can be called from C#.

For your scenario, I'd recommend calling GetCurrentProcess to get the handle to the current process and passing it to GetProcessTimes to get the user and kernel times. I ran a brief test and got reasonable looking results with this approach.

Here's a complete C# class that uses P/Invoke to make the call:

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)
        };
    }
}

Usage:

var times = DebugProcessTimes.GetProcessTimes();

这篇关于WinRT应用程序有什么方法可以衡量自己的CPU使用率?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆