- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我想访问在具有不同本地化的系统上运行的应用程序中的“处理器时间 %”计数器。
为此,我想通过其索引访问计数器,该索引保证是唯一的(请参阅 https://support.microsoft.com/en-us/kb/287159)。
下面的代码有效并为我提供了当前语言环境的正确结果,但要打开性能计数器,我还需要计数器的类别名称(请参阅 PerformanceCounter
类的构造函数)以及实例名称:
[DllImport("pdh.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern UInt32 PdhLookupPerfNameByIndex(string szMachineName, uint dwNameIndex, StringBuilder szNameBuffer, ref uint pcchNameBufferSize);
void Main()
{
var buffer = new StringBuilder(1024);
var bufSize = (uint)buffer.Capacity;
PdhLookupPerfNameByIndex(null, 6, buffer, ref bufSize);
Console.WriteLine(buffer.ToString());
var counter = new PerformanceCounter(/* category??? */, buffer.ToString(), /* instance??? */);
}
如何获取该类别和实例名称?
另见: Retrieve performance counter value in a language-independent way ,它描述了同样的问题,但没有提供解决方案。
最佳答案
您误解了 PdhLookupPerfNameByIndex() 的工作原理。它的工作不是映射性能计数器而是映射字符串。它应该用于计数器的类别及其名称。不适用于计数器的实例,如果适用,它未本地化。
查看其功能的最佳方法是使用 Regedit.exe。导航到 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib。请注意“009”键,其计数器值具有到英文字符串映射的索引。双击计数器并将框的内容复制粘贴到文本编辑器中,以便更好地查看。 “CurrentLanguage”键是相同的映射,但使用本地化名称。
因此 PdhLookupPerfNameByIndex() 使用 CurrentLanguage 键,使用您在上一步中获得的列表可以知道字符串的索引号。如知识库文章底部所述(令人困惑)的另一种方法是首先从“009”注册表项中查找索引号。这使您可以将英文字符串翻译成本地化字符串。请注意,知识库文章记录了错误的注册表项位置,不知道为什么。
请记住,它并不完美,正如知识库文章中所指出的,这些映射仅针对“基本”计数器存在,而“009”键是不明确的,因为某些索引映射到相同的字符串。在本地化的 Windows 版本上进行测试非常重要。
一些代码同时实现了这两种方式:
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Win32;
using System.Diagnostics;
using System.Runtime.InteropServices;
public static class PerfMapper {
private static Dictionary<string, int> English;
private static Dictionary<int, string> Localized;
public static PerformanceCounter FromEnglish(string category, string name, string instance = null) {
return new PerformanceCounter(Map(category), Map(name), instance);
}
public static PerformanceCounter FromIndices(int category, int name, string instance = null) {
return new PerformanceCounter(PdhMap(category), PdhMap(name), instance);
}
public static bool HasName(string name) {
if (English == null) LoadNames();
if (!English.ContainsKey(name)) return false;
var index = English[name];
return Localized.ContainsKey(index);
}
public static string Map(string text) {
if (HasName(text)) return Localized[English[text]];
else return text;
}
private static string PdhMap(int index) {
int size = 0;
uint ret = PdhLookupPerfNameByIndex(null, index, null, ref size);
if (ret == 0x800007D2) {
var buffer = new StringBuilder(size);
ret = PdhLookupPerfNameByIndex(null, index, buffer, ref size);
if (ret == 0) return buffer.ToString();
}
throw new System.ComponentModel.Win32Exception((int)ret, "PDH lookup failed");
}
private static void LoadNames() {
string[] english;
string[] local;
// Retrieve English and localized strings
using (var hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64)) {
using (var key = hklm.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009")) {
english = (string[])key.GetValue("Counter");
}
using (var key = hklm.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\CurrentLanguage")) {
local = (string[])key.GetValue("Counter");
}
}
// Create English lookup table
English = new Dictionary<string, int>(english.Length / 2, StringComparer.InvariantCultureIgnoreCase);
for (int ix = 0; ix < english.Length - 1; ix += 2) {
int index = int.Parse(english[ix]);
if (!English.ContainsKey(english[ix + 1])) English.Add(english[ix + 1], index);
}
// Create localized lookup table
Localized = new Dictionary<int, string>(local.Length / 2);
for (int ix = 0; ix < local.Length - 1; ix += 2) {
int index = int.Parse(local[ix]);
Localized.Add(index, local[ix + 1]);
}
}
[DllImport("pdh.dll", CharSet = CharSet.Auto)]
private static extern uint PdhLookupPerfNameByIndex(string machine, int index, StringBuilder buffer, ref int bufsize);
}
示例用法:
class Program {
static void Main(string[] args) {
var ctr1 = PerfMapper.FromEnglish("Processor", "% Processor Time");
var ctr2 = PerfMapper.FromIndices(238, 6);
}
}
我只能访问英文版的 Windows,因此不能保证本地化版本的准确性。请通过编辑这篇文章来纠正您遇到的任何错误。
关于c# - 按索引获取 PerformanceCounter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33804402/
以下段落使我感到困惑: 来自文章:Acquiring high-resolution time stamps When you need time stamps with a resolution o
我有六台机器要使用 perfmon 进行监控。我想在所有六个计数器上使用相同的一组计数器。有没有办法设置模板,以便我可以一次指定这些计数器,然后根据此模板设置其他数据收集器?还是我真的必须手动设置每个
我正在尝试设置我的 Azure Web 应用程序以包含第三方软件的使用,这似乎需要访问 PerformanceCounters。在本地,这工作正常,但是当我在 Azure 中运行它时,出现以下错误:
我用perf脚本命令查看perf.data文件的结果,但我不是很明白每一列的含义。例如,如果我有以下结果: perf 3198 [000] 13156.201238: bus-cycles: ff
我想知道是否有用于精确时间测量(如函数的执行时间)的“.net 集成”解决方案?目前我正在使用 Kernel32 的 PerformanceCounters。 [DllImport("Kern
我尝试使用 PerformanceCounter 来监控域环境中的远程服务器信息,例如: var counter = new PerformanceCounter("PhysicalDisk", "D
我正在使用 System.Data PerfomanceCounter 类,并且我找到了一些关于如何检索磁盘空间或 CPU 使用率的非常具体的示例。 但是我找不到关于以下可能值的文档: Perfoma
我知道使用 Perfmon.msc 您可以创建自定义性能计数器,并且通过使用计数器日志,您可以将计数器值写入文本文件。 我也明白我也可以通过使用 System.Diagnostics.Performa
我正在研究电荷平衡系统,因此我需要知道每台机器的电荷。 PerformanceCounter 似乎是可行的方法,但创建第一个需要 38 到 60 秒。然而,每个后续的新 Counter 或“NextV
我想访问在具有不同本地化的系统上运行的应用程序中的“处理器时间 %”计数器。 为此,我想通过其索引访问计数器,该索引保证是唯一的(请参阅 https://support.microsoft.com/e
我在一台服务器上工作,它从 PerformanceCounters 读取“% CPU”和“可用内存”。它在我的开发机器上运行良好。但是在实际的服务器上,读取这两个 PerformanceCounter
我有一个 Windows 服务,它跨多个线程运行框架的实现。每个正在运行的实例都有一些我需要跟踪的共同点,例如,处理的项目数、上次处理项目的时间等。在此基础监控数据之上,我想在框架允许实现动态添加自己
我正在使用 C# 的“PerformanceCounter”类来计算“内存”类别下的以下 2 个计数器“可用字节数”和“使用中的 promise 字节数百分比”。 Perfor
我不知道为什么,但是很多电脑在执行以下操作时挂起: void Init() { net1 = new List(); net2 = new List(); foreach (s
我正在制作一个程序,我需要从性能计数器中获取一些值。 目前一切正常。但是,当我尝试获取特定 IIS 站点的“Requests/Sec”计数器时,我没有获得任何值,比如它根本没有更新。但是,如果我在我的
我在使用 PerformanceCounter 时遇到问题,我想获取 CPU 温度,但我只找到了这个: PerformanceCounter tempCount = new PerformanceCo
我在我的应用程序中使用 QueryPerformanceCounter() 函数来测量时间。此功能还用于提供我的应用程序生命周期的时间线。最近我注意到其他时间函数的时间有偏差。最后,我写了一个小测试来
伙计们,我有以下代码: using System.Diagnostics; private PerformanceCounter diskRead = new PerformanceCounter()
我正在尝试了解如何收集计算机上每个处理器的当前使用百分比。如果我使用“System.Environment.ProcessorCount;”我可以获得计算机上的处理器数量,它当前返回“2”。我不知道自
我正在尝试手动将一些 PerformanceCounters 发送到 ApplicationInsights。 我尝试使用以下正文直接发布到 https://dc.services.visualstu
我是一名优秀的程序员,十分优秀!