寫在前面:
作為Web應用開發前線的一枚小兵,每看到“性能”一詞總有種要亮瞎眼的感覺,說到“性能”那就不能不提“數據”,在程序猿、攻城師中不是流行這樣一句話嗎?“無圖無真相”,誰要說誰開發的應用性能有多好多好,那么要亮瞎我們這些小兵的眼睛,就不得不拿出“數據”來說話啦,顯然,我們有一個能夠為我們提供“數據”的工具是多么的重要。今天就來學習一下使用C#是如何實現計數器的?(本文側重於具體實現)
簡要Windows性能監視器:
打開Windows性能監視器的步驟如下:
開始→運行→perfmon→確定


在這里我們可以選擇添加我們要監控的計數器,比如:cpu使用率、內存使用量等,作為asp.net攻城師我們還可以使用它來監控我們站點的請求隊列、應道隊列數量、請求總數等。比如我們要開可用內存的信息:

可用內存大小事實數據如下:

瞬間感覺到在微軟懷抱下的孩紙好幸福有木有。好啦接下來我們來看看C#是如何調用它的,並且是如何自定義自己的計數器的呢?
C#如何調用本地主機Windows性能監視器獲取數據
上代碼:
using System;
using System.Collections.Generic;
using System.Text;
//應引用此名門空間
using System.Diagnostics;
using System.Threading;
namespace Performance_Demo
{
class Class1
{
static void Main(string[] arge)
{
//性能計數器組件類
PerformanceCounter cpu = new PerformanceCounter("Memory", "Available MBytes", "");
while (true)
{
Console.WriteLine("{0} MB",cpu.NextValue());
Thread.Sleep(1000);
}
}
}
}
結果如下:

代碼很簡單,最主要的就是一個PerformanceCounter類的實例cpu,PerformanceCounter類有5個構造函數重載,就代碼中的構造函數講述,構造函數為new PerformanceCounter(“計數器類型名稱”,“計數器名稱”,“計數器實例名稱”),(如果該計數器為單實例,那么計數器實例名稱可為“”)。可使用實例的NextValue()方法獲取當前值。
呵呵,當你看到代碼時會說“如此 so easy”,但你可能對“計數器類型名稱”,“計數器名稱”,“計數器實例名稱”這三個名稱有點糊塗啦吧,別着急,先看一張圖:

對這張圖不陌生吧,沒錯,添加可用內存計數器時見過,那么“1”就是“計數器類型名稱”,“2”就是“計數器名稱”,“3”就是“計數器實例名稱”(應為該計數器是單實例的,所以“3”下面沒有具體的實例),所以三者的關系我們可以歸納為:計數器類型》計數器》計數器實例。趕緊試一下吧小伙伴們。。。
C#如何調用遠程主機Windows性能監視器獲取數據
上代碼
class Class3
{
//訪問遠程主機的性能監視器
static void Main(string[] arge)
{
//先於遠程IP建立連接
string tmpstr = "net use \\\\" + "172.16.164.000" + "\\ipc$ " + "密碼" + " /user:" + "用戶名";
RunDOS(tmpstr);
//性能計數器組件類
PerformanceCounter cpu = new PerformanceCounter("Memory", "Available MBytes", "", "172.16.164.215");
while (true)
{
Console.WriteLine("{0} MB", cpu.NextValue());
Thread.Sleep(1000);
}
}
//使用DOS運行命令
static void RunDOS(string DOS)
{
Process p = null;
p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = true;
p.Start();
string strOutput = "";
p.StandardInput.WriteLine(DOS);
p.StandardInput.WriteLine("exit");
while (p.StandardOutput.EndOfStream)
{
strOutput = p.StandardOutput.ReadLine();
}
p.WaitForExit();
p.Close();
}
}
代碼也很簡單,與調用本地主機不同之處就是多了一段運行DOS命令的代碼,目的就是先與遠程主機建立連接,需要指定遠程主機IP、用戶名、密碼(可以為一般管理員身份),此時需要注意的是遠程主機上的“Remote Registry”服務應處於啟動狀態,目的是為了能讓遠程用戶能修改此計算機上的注冊表。
C#如何自定義計數器
前面我們學習如何使用C#調用Windows性能監視器,來獲取系統的各個計數器實時數據,那么我們可不可以自己定義一個計數器,並且添加到性能監視器中供我們實時查看呢?答案是肯定的。試想一下我們在日常開發當中會有類似這樣的需求:我們有一個隊列(可能是各種命令啊或者是消息啊、訂單啊等等),那么我們想有一個可視化的東西來監控一下這個隊列中積壓了多少內容,當然啦我們萬能的攻城師們肯定希望積壓數量永遠是0啦,哈哈,此時我們就可以為我們的隊列設計一個計數器,那么我們就可以在Windows性能監視器中找到並且實時查看隊列積壓情況啦。(開始動手吧)
先上代碼:
(代碼就語無倫次吧,神馬都不講究啦)
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Collections;
namespace Performance_Demo
{
class Class2
{
//我的隊列
static Queue<int> myQueue = new Queue<int>();
//計數器實例
static PerformanceCounter counter1 = null;
static void Main(string[] arge)
{
//計數器類型名稱
string CategoryName = "a_yigebeiyiwangdebaozi";
//計數器名稱
string CounterName = "a_yigebeiyiwangdebaozi_counter1";
if (PerformanceCounterCategory.Exists(CategoryName))
{
PerformanceCounterCategory.Delete(CategoryName);
}
CounterCreationDataCollection ccdc = new CounterCreationDataCollection();
//計數器
CounterCreationData ccd = new CounterCreationData(CounterName, "myCounter", PerformanceCounterType.NumberOfItems64);
ccdc.Add(ccd);
//使用PerformanceCounterCategory.Create創建一個計數器類別
PerformanceCounterCategory.Create(CategoryName, "", PerformanceCounterCategoryType.MultiInstance, ccdc);
//初始化計數器實例
counter1 = new PerformanceCounter();
counter1.CategoryName = CategoryName;
counter1.CounterName = CounterName;
counter1.InstanceName = "myCounter1";
counter1.InstanceLifetime = PerformanceCounterInstanceLifetime.Process;
counter1.ReadOnly = false;
counter1.RawValue = 0;
while (true)
{
EnqueueQueue();
System.Threading.Thread.Sleep(1000);
DequeueQueue();
}
}
static void EnqueueQueue()
{
int C = new Random().Next(10);
for (int i = 0; i < C; i++)
{
myQueue.Enqueue(i);
//計數器加一
counter1.Increment();
}
}
static void DequeueQueue()
{
int C = new Random().Next(20);
for (int i = 0; i < C; i++)
{
if (myQueue.Count == 0)
break;
myQueue.Dequeue();
//計數器減一
counter1.Decrement();
}
}
}
}
我們先在性能監視器中找到我們的計數器如下:

我們隊列的實時數據如下:

好啦,我們的計數器完成啦!
快下班啦就寫到這里,如有錯誤請土豪們指正。
