今天我在工作中被要求创建一个工具,让最终用户在遇到“性能问题”时运行它。这是对越来越多的几台计算机和/或应用程序遇到极端性能问题的报告的反应。由于大量的报告,我们需要这些数据收集自动发生,所以我们可以在以后深入数据。以计算机“性能快照”
我已经设置了一个后端来收集信息,并且已经收集了一堆信息,但是我在收集进程的性能数据时遇到了问题。这是我看着:
1)使用System.Diagnotics.Process.GetProcesses():
这让我所有正在运行的特效,这是很好的一个列表,但是这需要应用程序能够运行显然提升了,因为每当我想要收集UserProcessorTime时它都会抛出异常,即使这些信息对于任务管理器中的每个非管理用户来说都适用于他自己的进程。即使作为成熟的管理员用户运行,它也会引发异常。
2)使用的PerformanceCounter
性能计数器似乎很强大,但我已经遇到了麻烦,通过匹配的进程ID性能计数器,它似乎性能计数器大多用于在一段时间内跟踪性能。情况并非如此。我们主要是在寻找一种进程失控的模式。
基本上,我们正在寻找(或多或少)是在任务管理器的进程列表(进程名称,CPU周期,私有内存使用情况)中显示的信息的快速快照,而且无需应用程序运行提升(进程列表可以限制为用户特效)。这与我所问的是一致的。
编辑:下面是一些代码,我试图用,很抱歉不能提供任何早期
下面是试图使用性能计数器来获得“%处理器时间”和实例“工作集 - 私人”适用于所有流程。
PerformanceCounterCategory perfCategory = PerformanceCounterCategory.GetCategories().First(c => c.CategoryName == "Process");
Console.WriteLine("{0} [{1}]", perfCategory.CategoryName, perfCategory.CategoryType);
string[] instanceNames = perfCategory.GetInstanceNames();
if (instanceNames.Length > 0)
{
foreach (string instanceName in instanceNames)
{
Console.WriteLine(" {0}", instanceName);
PerformanceCounter[] counters = perfCategory.GetCounters(instanceName);
foreach (PerformanceCounter counter in counters)
{
if (counter.CounterName == "Working Set - Private")
{
Console.WriteLine(" {0} - {1}", counter.CounterName, counter.RawValue, counter.RawValue/1024);
}
if (counter.CounterName == "% Processor Time")
{
Console.WriteLine(" {0} - {1}", counter.CounterName, counter.RawValue);
}
}
}
}
为“工作集 - 私人”的结果是斑上,但对于“%处理器时间”,这些价值观毫无任何意义。
下面是输出的一个例子,你可以看到,处理器时间百分比结果毫无任何意义:
WDExpress#1
% Processor Time - 378146424
Working Set - Private - 136257536
taskhost
% Processor Time - 129480830
Working Set - Private - 1835008
svchost
% Processor Time - 2877438445
Working Set - Private - 4096000
IpOverUsbSvc
% Processor Time - 15600100
Working Set - Private - 1236992
vncserver
% Processor Time - 238213527
Working Set - Private - 2555904
chrome#21
% Processor Time - 1652830595
Working Set - Private - 56799232
编辑2:
斯科特已经提供了答案的很大一部分,但我现在仍然面临着其他问题,下面两个选项:
快速,准确,炸弹CPU
counter.NextValue(); Console.WriteLine("{0} - {1}", counter.CounterName, counter.NextValue());
调用NextValue()后,两次对方收集数据非常快,但相当多轰击我的CPU(和结果可能是次优的)。
准确,速度很慢,容易在CPU
counter.NextValue(); System.Threading.Thread.Sleep(1000); Console.WriteLine("{0} - {1}", counter.CounterName, counter.NextValue());
另一种选择是将每个呼叫到NextValue之间Thread.sleep代码()上() ,但这使得它非常慢(因为我们可能谈论的是100多个进程)
而你的问题是什么?如何处理你所尝试的代码片段? – techvice 2014-11-20 22:40:15
“我基本上可以如何快速查看任务管理器进程列表中显示的信息(进程名称,cpu周期,专用内存使用情况),而不需要应用程序运行提升”。我没有提供任何代码片断,因为我没有任何编写代码的麻烦,我只是不确定要使用哪些组件。另外我在睡觉之前写下了这个:) – 2014-11-20 22:44:43
如何使用WMI访问流程信息?有些是这样的:http://www.codeproject.com/Articles/12138/Process-Information-and-Notifications-using-WMI – techvice 2014-11-20 22:49:33