PerformanceCounter蛋痛的设计
在.NET下对进程的性能计数可以使用PerformanceCounter,通过该对象可以对进程的CPU,内存等信息进行统计.对于正常使用来说这个对象还是很方便,但对于同一名称的多个进程进行性能计数那真是可以无比蛋痛...详细说一下PerformanceCounter对多个同一名称的进程计数所面对的问题.
应用情况
PerformanceCounter是通过进程实例名来监控计数,但这个实例名是操作系统实时动态分配的,如果同一名称的进程只有一个那就比较好处理.如果同一名称的进程有多个那悲剧的事情就来的,随着同一名称的进程创建和关闭会影响到其他同一名称进程的实例名.这样会导致相应的PerformanceCounter和进程的对应关系完全错乱...(真是无法理解.NET对这个的实现为什么不用PID)
假设现在有个ams-p.exe应用程序,依次分别打开三次,那对应的进程实例名是:
1)ams-p.exe [pid:7012]
2)ams-p.exe#1 [pid:7013]
3)ams-p.exe#2 [pid:7014]
由于实例名windows系统实时分配的,一旦同一名称的进程数量发现变化那对应进程的实例名也会变.针对上面情况当2被关闭后那实例对应的关系可以是.
1)ams-p.exe [pid:7012]
3)ams-p.exe#1 [pid:7014]
这样就会导致3对应的实例名不存在,从而导致PerformanceCounter上的统计错误,如果对应同一名称的进程数量更多,中间其中一个进程关闭那就会有大量的PerformanceCounter统计和进程对应关系就都会存在错误的.
解决办法
虽然有解决方法,但做法都是非常蛋痛的,监控Process的Exite事件然后根据退出情况来调整实例名和PID的对应关系,不过这种方式是存在一些问题,如果其他应用也是这个进程名又是通过其他渠道打开你未及时捕抓绑定Exite事件,那就会导致计数错误的悲剧事件发生.而另一种解决方法就比较全面点,在执行所有PerformanceCounter前行把当前系统该名称的进程信息获取上载并建立一个实时的实例名和PID对应关系,然后在执行PerformanceCounter后记录对应实例名的PID计数情况.具体代码如下:
class CPUCounter:IDisposable
{
public CPUCounter(string processName)
{
mProcessName = processName;
mTimer = new System.Threading.Timer(GetUsage, null, 1000, 1000);
} private System.Threading.Timer mTimer; private string mProcessName; private Dictionary<int, float> mProcessCpuUsage = new Dictionary<int, float>(); private List<CounterItem> mCounters = new List<CounterItem>(); private Dictionary<string, int> mProcessIDs = new Dictionary<string, int>(); public float ProcessUsage(int pid)
{
float result = 0;
mProcessCpuUsage.TryGetValue(pid, out result);
return result;
} private void OnCreateCounter(string processname)
{
CounterItem item = mCounters.Find(e => e.ProcessName == processname);
if (item == null)
{
item = new CounterItem();
item.Counter = new PerformanceCounter();
item.Counter.CategoryName = "Processor";
item.Counter.CounterName = "% Processor Time";
item.Counter.InstanceName = processname;
}
item.Enabled = true;
} private void GetUsage(object state)
{
mProcessIDs.Clear();
Process[] ps = Process.GetProcessesByName(mProcessName);
List<CounterItem> disposeditems = new List<CounterItem>();
if (ps.Length == 1)
{
mProcessIDs.Add(mProcessName, ps[0].Id);
OnCreateCounter(mProcessName);
}
else
{
for (int i = 1; i < ps.Length; i++)
{
mProcessIDs.Add(mProcessName + "#" + i, ps[i].Id);
OnCreateCounter(mProcessName + "#" + i);
}
}
foreach (CounterItem item in mCounters)
{
if (item.Enabled)
{
mProcessCpuUsage[mProcessIDs[item.ProcessName]] = item.Counter.NextValue();
item.Enabled = false;
}
else
{
disposeditems.Add(item);
}
}
if(disposeditems.Count>0)
foreach (CounterItem item in disposeditems)
{
mCounters.Remove(item);
}
} class CounterItem
{
public string ProcessName { get; set; } public System.Diagnostics.PerformanceCounter Counter
{
get;
set;
} public bool Enabled
{
get;
set;
}
} public void Dispose()
{
if (mTimer != null)
mTimer.Dispose();
}
}
如果有更好办法的同学不防分享一下.
PerformanceCounter蛋痛的设计的更多相关文章
- 鸡和蛋的OO设计
一个题目:用类图表示出鸡和蛋的关系. 第一版: 第二版: 一个鸡可以下N个蛋,一个蛋可以浮出0或者1个鸡. 问题是公鸡不会下单,第三版:
- 关于变量参数的传递,python让人蛋痛的地方
def find_file(file_table): with open(file_table, 'r', encoding='utf-8') as read_f: line_dict = {} fo ...
- python蛋痛的依赖管理
java有maven 来统一管理项目依赖.初学python不久还没发现类似这样的工具.只有暂时用这个方法来手动操作了. 你可以用pip导出你的dependency: $ pip freeze > ...
- Swift 玩转 3D Touch 之 Peek & Pop
什么是3D Touch 3D Touch 是iOS9之后专为 iPhone6s 机型加入的新特性,这一新技术移植于 Mac Book 上的 ForceTouch 更准确地说应该是 ForceTouch ...
- 你真的知道HTML吗?
经过几次面试当中,被问及到最基础的东西,没想到回答不上来,有点蛋痛,今天特地的复习了一下!! 内容: 1.Doctype(文档类型)的作用是什么?有多少文档类型? 2.浏览器标准模式和怪异模式之间的区 ...
- 模块化的JavaScript开发的优势在哪里
如今模块化的 JavaScript 的开发越来越火热,无论是模块加载器还是优秀的 JavaScript 模块,都是层出不穷.既然这么火,肯定是有存在的理由,肯定是解决了某些实际问题.很多没接触过模块化 ...
- ThoughtWorks开发持续集成及部署利器:Go
持续集成及部署利器:Go Go是一款先进的持续集成和发布管理系统,由ThoughtWorks开发.(不要和Google的编程语言Go混淆了!)其前身为Cruise,是ThoughtWorks在做咨 ...
- 在网络通讯中应用Protobuf
在网络通讯中应用Protobuf Protobuf的设计非常适用于在网络通讯中的数据载体,它序列化出来的数据量少再加上以K-V的方式来存储数据,对消息的版本兼容性非常强:还有一个比较大的优点就是有着很 ...
- as3设计模式乱用之工厂模式
好久没写技术相关的日记了,一忙,二懒,三则被这单调的生活熏得没什么感悟. 其实这篇日记早就想写了,项目开发初期的时候,带学生.经常看到那种乱用设计模式的现象.一方面,公司面试人的时候喜欢问设计模式,另 ...
随机推荐
- SQL Server Agent Job 中用Powershell将备份文件拷贝到AWS S3
SQL Server 数据库备份后,如何再复制一份到AWS S3 上,步骤和需要注意的地方如下: 1. 首先在SQL Server 中创建一个Credential 2. 授权这个Credential ...
- 【nuget】PackageReference
.net 爬虫 <PackageReference Include="HtmlAgilityPack" Version="1.9.0" /> < ...
- 2019-3-22KeyDown,KeyPress 和 KeyUp 事件
研究了一下KeyDown,KeyPress 和 KeyUp 的学问.让我们带着如下问题来说明: 1.这三个事件的顺序是怎么样的? 2.KeyDown 触发后,KeyUp是不是一定触发? 3.三个事件的 ...
- Python+Tkinter 实现计算器功能
#=================================================================================== import tkinter ...
- mysql数据表增删改查
http://www.runoob.com/mysql/mysql-tutorial.html 一.MySQL 创建数据表 创建MySQL数据表需要以下信息: 表名 表字段名 定义每个表字段 语法 以 ...
- GDKOI2017滚粗记
Preface 比赛成绩非常烂,却腐败得非常爽,但是gmh大爷因为和我们腐败,变得更强. 比赛策略有点问题,拼命想正解而没了暴力分 数论题做得比较少,导致只会找规律.知识点需要补充,如AC自动机,启发 ...
- CSS3 常用属性
1------border-radius (盒子圆角 border-radius :border-radius:5px 4px 3px 2px; 左上,右上,右下,左下 2------如果将一个正方形 ...
- 可视化利器Visdom
可视化利器Visdom 最近在使用Pytorch炼丹,单纯地看命令行输出已经无法满足调试的需求,尝试了facebook开源的visdom,感觉非常优雅,支持numpy和torch 安装 $ pip i ...
- linux configure 应用
linux下configure命令详细介绍 2018年01月11日 15:02:20 冷月霜 阅读数:705 标签: configure 更多 个人分类: 数据库技术 Linux环境下的软件安装, ...
- window server 2008 安装Oracle10g
oracle安装都大同小异. 开始安装步骤 输入完之后点击下一步 这时候稍等一会儿. 这时候也要稍等一会儿. 直接安装. 设置口令管理,设置SCOTT的密码为tiger就好了. 这时候稍等一会儿. o ...