我需要使用C#(或VB.Net)获取特定进程使用的CPU周期数.此信息可在Sysinternal的Process Explorer中的Process properties弹出窗口中找到.例如,我正在使用此消息发布的浏览器目前使用了18,521,360,165个cyles(给予或接受了几亿).有谁知道如何从.Net应用程序获取此信息?我知道如何获得CPU使用率(百分比),但这不是我正在寻找的.我需要一种方法来比较在不同时间运行的两个不同进程之间的CPU使用情况.
谢谢你,马特
更新:
为什么我需要这个?我是本地.Net用户组的领导者,我们正在运行代码挑战,开发人员提交代码来解决问题.我需要一种方法来衡量一个条目与另一个条目的表现.目前我正在使用计时器来衡量性能.服务器100%专用于此,但这并不能保证可能同时发生其他事情.显然,这是各种潜在问题,但总的来说,它是相当准确的.测量所使用的CPU周期数将是一种几乎万无一失的方法来衡量某人的入口对另一个人的表现.我确信有人可以在这一点上打洞 - 不需要在这一点上尝试.;-)我希望这有助于解释我的问题背后的原因以及为什么计时器不足以解决我的问题.
现代CPU拥有相当多的性能指标 - http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-system-programming- manual-325384.html如何阅读它们?我对缓存未命中和分支错误预测感兴趣.
我有以下类返回IIS当前每秒请求数.我每分钟调用RefreshCounters以保持每秒请求数值的刷新(因为它是平均值,如果我保持太长时间,旧值会影响结果太多)......当我需要显示当前的RequestsPerSecond时,我会调用该属性.
public class Counters
{
private static PerformanceCounter pcReqsPerSec;
private const string counterKey = "Requests_Sec";
public static object RequestsPerSecond
{
get
{
lock (counterKey)
{
if (pcReqsPerSec != null)
return pcReqsPerSec.NextValue().ToString("N2"); // EXCEPTION
else
return "0";
}
}
}
internal static string RefreshCounters()
{
lock (counterKey)
{
try
{
if (pcReqsPerSec != null)
{
pcReqsPerSec.Dispose();
pcReqsPerSec = null;
}
pcReqsPerSec = new PerformanceCounter("W3SVC_W3WP", "Requests / Sec", "_Total", true);
pcReqsPerSec.NextValue();
PerformanceCounter.CloseSharedResources();
return null;
}
catch (Exception ex)
{
return ex.ToString();
} …
Run Code Online (Sandbox Code Playgroud) 性能指标是EVIL.不要使用它们.
if(PerformanceCounterCategory.Exists("ILoveYou") ) // is true
{
PerformanceCounterCategory.Delete("ILoveYou");
//throws exception The **configuration registry** key is invalid
}
Run Code Online (Sandbox Code Playgroud)
at System.Diagnostics.PerformanceCounterLib.RegisterFiles(String arg0, Boolean unregister)
at System.Diagnostics.PerformanceCounterLib.UnregisterCategory(String categoryName)
at System.Diagnostics.PerformanceCounterCategory.Delete(String categoryName)
at WindowsFormsApplication1.Program.SetupCategory()
Run Code Online (Sandbox Code Playgroud)
所有我发现的是:http: //blogs.msdn.com/b/oanapl/archive/2009/04/24/fix-corrupted-performance-counters.aspx (使用LODCTR/R)
它没有帮助.因为我不知道他们在说什么文件.any1还有其他想法吗?
PS我用windows xp SP3可能这个问题?我知道除非我取消页面文件,否则应该完全支持性能计数器.
这清楚我的问题是我无法卸载我的计数器.
我正在调试一个几天后几乎没有响应的C#应用程序.应用程序每秒计算内存/ CPU使用率,并将其显示在主UI的页脚中.
无响应的原因是因为获取RawValue
a PerformanceCounter
("工作集 - 私有")所花费的时间.几天之后,需要几乎一秒的时间来获取RawValue
,冻结主UI线程.如果我重新启动计算机,一切都会再次快速运行几天,直到它慢慢变得不那么敏感.如果我在没有PerformanceCounter
代码(它的开源)的情况下重新编译这个应用程序,它会立即正常运行.
要排除它是应用程序,这里有一些示例代码完全相同:
static void Main(string[] args)
{
using (var memoryWorkingSetCounter = new PerformanceCounter("Process", "Working Set - Private", Process.GetCurrentProcess().ProcessName, true))
{
while (!Console.KeyAvailable)
{
var memoryWorkingSetSw = new Stopwatch();
memoryWorkingSetSw.Start();
var memoryWorkingSetValue = memoryWorkingSetCounter.RawValue;
memoryWorkingSetSw.Stop();
Console.WriteLine(memoryWorkingSetValue.ToString());
Console.WriteLine(memoryWorkingSetSw.Elapsed.ToString());
Thread.Sleep(TimeSpan.FromSeconds(1));
}
}
Console.Read();
}
Run Code Online (Sandbox Code Playgroud)
我让它运行了大约2.5天,并Elapsed
以毫秒为单位绘制了时间:
什么可能导致Windows中的性能计数器随着时间的推移变得缓慢?另一个应用程序可能不清理它?有没有办法调试哪些应用程序也在查看此性能计数器?我在Windows 10上.
如果有多个具有相同名称的实例,Windows中的大多数实例性能计数器似乎自动(?)最后都有#n.
例如:如果在Perfmon中查看该Process
类别,您将看到:
...
dwm
explorer
explorer#1
...
Run Code Online (Sandbox Code Playgroud)
我有两个explorer.exe
进程,所以第二个计数器的名称附加了#1.
当我尝试在.NET应用程序中执行此操作时:
PerformanceCounterCategory.Create
带有a 的实例CounterCreationDataCollection
).当我第二次打开计数器(在另一个过程中)时,它会打开同一个计数器.这意味着我有两个进程争夺计数器.
在对文件PerformanceCounter.InstanceName
,各国#
未在允许的名称.
那么:我如何拥有实际多实例的多实例性能计数器?第二个(和后续的)实例#n
附加到名称的位置?
那就是:我知道我可以将进程ID(例如)放在实例名称上.这有效,但有一个不幸的副作用,即重新启动进程会产生新的PID,并且Perfmon继续监视旧计数器.
更新:
我正在创建类别(和计数器),如下所示:
const string categoryName = "Test App";
const string counterName = "Number of kittens";
string instanceName =
Path.GetFileNameWithoutExtension(
Process.GetCurrentProcess().MainModule.FileName);
if (!PerformanceCounterCategory.Exists(categoryName))
{
var counterCreationDataCollection = new CounterCreationDataCollection
{
new CounterCreationData(counterName, "",
PerformanceCounterType.NumberOfItems32)
};
PerformanceCounterCategory.Create(categoryName, "",
PerformanceCounterCategoryType.MultiInstance,
counterCreationDataCollection);
}
Run Code Online (Sandbox Code Playgroud)
我打开柜台如下:
PerformanceCounter counter = new PerformanceCounter(
categoryName, counterName, instanceName, readOnly: …
Run Code Online (Sandbox Code Playgroud) 我试图做这样的事情这在C#.我发现如何使用此链接中的 P/Invoke 从 C#调用Win32方法.但是我在实现P/Invoke方面遇到了一些困难.
例如,我想访问的方法之一是PdhOpenQuery,签名:
PDH_STATUS PdhOpenQuery(
__in LPCTSTR szDataSource,
__in DWORD_PTR dwUserData,
__out PDH_HQUERY *phQuery
);
Run Code Online (Sandbox Code Playgroud)
我认为相应的C#声明应该是这样的
[DllImport("Pdh.dll")]
static extern PDH_STATUS PdhOpenQuery(LPCTSTR szDataSource,
DWORD_PTR dwUserData, out PDH_HQUERY *phQuery);
Run Code Online (Sandbox Code Playgroud)
我的问题:
什么是LPCTSTR,以及它在C#中映射的数据类型是什么?
如何映射指针类型DWORD_PTR?pinvoke文章说DWORD映射到UInt32,但指针怎么样?
我认为PDH_STATUS和PDH_HQUERY是库的特定结构(我还不确定).我该如何映射这些?
什么是正确的方法声明,以及如何正确地调用它?
我试图弄清楚是否有一个库给我一些接近相当于Windows自定义性能计数器的东西(这里描述http://geekswithblogs.net/.NETonMyMind/archive/2006/08/20/88549.aspx)
基本上,我正在寻找可用于跟踪应用程序中的全局计数器的东西,以及(理想情况下)通过定义良好的接口向其他应用程序/用户呈现该信息的东西.这些是应用统计; 像内存和磁盘这样的东西可以通过其他方式捕获,但我希望公开在我的应用程序生命周期中处理的吞吐量/事务/"小部件".
我见过这个问题:
还有这个
但这两者都不是我想要的.我不想写一个静态文件(毕竟这是动态信息;即使磁盘已满,我也应该能够得到它),而且如果可能的话,宁可避免使用自己开发的代码集.理想情况下,至少在Linux上,这些数据(我认为)会以某种方式通过/ proc浮出水面,虽然我不清楚是否可以从用户区域完成(这不太重要,只要它在某些方面浮出水面)给客户的方式.)
但回到问题的关键:是否有任何内置或合适的第三方库为我提供适用于我可以在Linux和其他*NIXy操作系统上使用的应用程序指标的自定义全局(线程安全,高性能)计数器?(并且可以从C/C++接口?)
如果您想查看此问题的原始表现,请阅读"原始问题"部分.
简而言之:我正在修改C++联合对象的一个字段,但这对其他字段没有任何影响,它的表现非常像一个结构.对于解决方案:请参阅我的回答.
tl; dr:不QueryPeformanceCounter
应该QuadPart
在提供的字段中返回它的值LONG_INTEGER
而不是HighPart
/ LowPart
?我无法找到任何特定于系统的地方,但似乎是这样.
我从Windows获得了一种奇特的行为QueryPeformanceCounter
.仔细考虑这个非常简单的用法,紧跟微软的例子:
#include <windows.h>
bool test()
{
LARGE_INTEGER start, end, freq;
if (!QueryPerformanceFrequency(&freq)) {
cout << "QueryPerformanceFrequency failed!\n";
return false;
}
QueryPerformanceCounter(&start);
Sleep(1000); // Simulate work
QueryPerformanceCounter(&end);
cout << "range: from " << start.QuadPart << " to " << end.QuadPart << endl;
return true;
}
Run Code Online (Sandbox Code Playgroud)
我得到以下输出:
range: from -3689348814741910324 to -3689348814741910324
Run Code Online (Sandbox Code Playgroud)
这似乎很随意,但事实并非如此.添加转储功能:
ostream& operator << (ostream& os, const LARGE_INTEGER& li) …
Run Code Online (Sandbox Code Playgroud) 在静态Stopwatch
构造函数中,我们可以看到以下代码,它基本上检查是否存在高分辨率性能计数器.
static Stopwatch()
{
if (!SafeNativeMethods.QueryPerformanceFrequency(out Frequency))
{
IsHighResolution = false;
Frequency = 0x989680L;
tickFrequency = 1.0;
}
else
{
IsHighResolution = true;
tickFrequency = 10000000.0;
tickFrequency /= (double) Frequency;
}
}
Run Code Online (Sandbox Code Playgroud)
在MSDN上,它说QueryPerformanceFrequency
:
检索高分辨率性能计数器的频率(如果存在)
然而,目前还不清楚它究竟存在的时候?我怀疑它通常存在于当前的机器上,但究竟不是吗?
这很有意思,因为当它不存在时,Stopwatch
变成仅仅DateTime.UtcNow
属性的包装.