我正在尝试使用不同的方法在WinRT中制作游戏图形,如果我的测试应用程序可以测量并显示自己的CPU使用情况,那就太好了,所以我可以比较不同的方法(ItemsControl与手动移动图像)与DirectX)。
在成熟的.NET中,我可以在两个已知的时间点读取Process.TotalProcessorTime,然后将增量处理器时间除以增量时间(根据需要调整处理器数量)。如果应用程序以完全信任的方式运行,我甚至可以找到dwm.exe的Process实例(因为它完成了将GUI放在屏幕上的所有繁重工作)并将其添加到我的CPU时间中。这是我在Game Graphics test suite的WinForms和WPF版本中采用的方法。
但是在WinRT中,System.Diagnostics.Process类不存在。如果有替代API,我不确定在哪里寻找它。
我可以打开任务管理器并将其设置为保持最佳状态,并在我的应用运行时随时关注它。这不太理想,因为(a)它覆盖了我的窗户的一部分,因此可能会略微扭曲结果; (b)我无法进行任何自己的聚合或记录结果(例如“这里是10秒范围内的平均CPU使用率”)。因此,如果有一些方法可以通过编程方式获得我的CPU使用率,我更喜欢这样,只是因为它给了我更多的灵活性。
WinRT应用有没有办法确定自己的CPU使用率?
答案 0 :(得分:1)
我不知道任何“已批准”的API可以从Windows应用商店应用中获取此信息。
但是,如果您只想在测试应用中执行此操作,则可以使用“未批准”的API。如果您使用未经批准的API,您的程序将无法通过WACK认证,也无法上传到商店,但在本地进行测试即可。请注意,当您调用未批准的API时无法保证,因此行为是正式未定义的,但许多函数都可以正常工作 - 至少在当前版本中是这样。
我在今年夏天早些时候写的一篇文章"printf debugging in Metro style apps"中演示了如何调用AllocConsole
。你可以用C#做类似的事情,使用P / Invoke来调用本机函数,或者编写一个可以从C#调用的C ++ Windows运行时组件。
对于您的场景,我建议调用GetCurrentProcess
来获取当前进程的句柄并将其传递给GetProcessTimes
以获取用户和内核时间。我进行了一次简短的测试,并用这种方法得到了合理的结果。
这是一个完整的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)
};
}
}
用法:
var times = DebugProcessTimes.GetProcessTimes();
答案 1 :(得分:0)
不幸的是,WinRT中没有相应的System.Diagnostics.Process类,至少目前没有(Missing reference to System.Diagnostics.Process和Accessing other processes in Win8 Metro-style app)。一些本机API暴露给WinRT(例如,请参阅How can I get the number of logical CPUs on WinRT?),但我找不到列表。