使用性能计数器检测应用程序的性能!
1. 创建一个简单的web service,这个演示程序就是把客户端对web service中的两个webmethod总访问量,每秒访问量,总出错次数,每秒出错次数以及调用延迟的情况在性能计数器中显示出来,web service中的代码相当简单,事实上基本上看不到延迟的存在,这也只是为了演示用。
2. 创建性能计数器,这里用一个简单的cs文件替代了installer文件,只需用csc命令讲下面的代码编译成exe文件,然后运行exe文件就可以在系统中创建自己的性能计数器。注意:我们并不需要做总访问次数和时间的除法运算来得到每秒的访问次数,PerformanceCounterType枚举类型专门负责这个,详细的信息请查阅msdn.
3.客户端的代码使用两个timer在tick事件中生成的随机数做循环调用模拟当前的访问量,并且在每次调用的时候更新计数器,代码很简单。
我的代码中UpdatePerfCounters方法的最后一个参数总是传的true,因为这两个web method太简单了,基本不会出错。^_^。实际用的时候会针对是否出现异常来决定是否更新和错误相关的计数器。
4.运行客户端的程序然后在运行里键入perfmon打开性能计数器管理窗口,找到MyPerfCategory性能对象,并且添加所有所有计数器的所有实例。
客户端演示效果图:
性能计数器效果图:
1using System;
2using System.Web;
3using System.Web.Services;
4using System.Web.Services.Protocols;
5
6[WebService(Namespace = "http://tempuri.org/")]
7[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
8public class Service : System.Web.Services.WebService
9{
10 public Service () {
11
12 //Uncomment the following line if using designed components
13 //InitializeComponent();
14 }
15
16 [WebMethod]
17 public string SayHelloTo(string someBody) {
18 return "Hello "+someBody;
19 }
20 [WebMethod]
21 public string SayWelcomeTo(string someBody)
22 {
23 return "Welcome, " + someBody;
24 }
25
26}
27
2using System.Web;
3using System.Web.Services;
4using System.Web.Services.Protocols;
5
6[WebService(Namespace = "http://tempuri.org/")]
7[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
8public class Service : System.Web.Services.WebService
9{
10 public Service () {
11
12 //Uncomment the following line if using designed components
13 //InitializeComponent();
14 }
15
16 [WebMethod]
17 public string SayHelloTo(string someBody) {
18 return "Hello "+someBody;
19 }
20 [WebMethod]
21 public string SayWelcomeTo(string someBody)
22 {
23 return "Welcome, " + someBody;
24 }
25
26}
27
2. 创建性能计数器,这里用一个简单的cs文件替代了installer文件,只需用csc命令讲下面的代码编译成exe文件,然后运行exe文件就可以在系统中创建自己的性能计数器。注意:我们并不需要做总访问次数和时间的除法运算来得到每秒的访问次数,PerformanceCounterType枚举类型专门负责这个,详细的信息请查阅msdn.
1using System;
2using System.Diagnostics;
3
4namespace ZZQ.Net.Demo
5{
6 public class Installer
7 {
8
9 public static void Main()
10 {
11 try
12 {
13 if (PerformanceCounterCategory.Exists("MyPerfCategory"))
14 {
15 PerformanceCounterCategory.Delete("MyPerfCategory");
16 }
17
18
19 CounterCreationDataCollection counterDatas = new CounterCreationDataCollection();
20
21 counterDatas.Add(new CounterCreationData("calls total", "number of service calls",
22 PerformanceCounterType.NumberOfItems64));
23 counterDatas.Add(new CounterCreationData("calls / sec", "number of service calls per second.",
24 PerformanceCounterType.RateOfCountsPerSecond64));
25 counterDatas.Add(new CounterCreationData("errors total",
26 "number of errors returned form service to the client.",
27 PerformanceCounterType.NumberOfItems64));
28 counterDatas.Add(new CounterCreationData("errors / sec",
29 "number of errors returned form service to the client per second.",
30 PerformanceCounterType.RateOfCountsPerSecond64));
31 counterDatas.Add(new CounterCreationData("average processing time",
32 "average call processing time in milliseconds.",
33 PerformanceCounterType.AverageCount64));
34 counterDatas.Add(new CounterCreationData("average processing time base", "",
35 PerformanceCounterType.AverageBase));
36 counterDatas.Add(new CounterCreationData("Processing time latency",
37 "Processing time in milliseconds.",
38 PerformanceCounterType.NumberOfItems32));
39
40 PerformanceCounterCategory.Create("MyPerfCategory", "It is just for demonstration purpose!", PerformanceCounterCategoryType.MultiInstance, counterDatas);
41
42
43 }
44 catch (Exception ex)
45 {
46 Console.WriteLine("Error occurred: " + ex.ToString());
47 }
48 Console.ReadLine();
49 }
50 }
51}
52
2using System.Diagnostics;
3
4namespace ZZQ.Net.Demo
5{
6 public class Installer
7 {
8
9 public static void Main()
10 {
11 try
12 {
13 if (PerformanceCounterCategory.Exists("MyPerfCategory"))
14 {
15 PerformanceCounterCategory.Delete("MyPerfCategory");
16 }
17
18
19 CounterCreationDataCollection counterDatas = new CounterCreationDataCollection();
20
21 counterDatas.Add(new CounterCreationData("calls total", "number of service calls",
22 PerformanceCounterType.NumberOfItems64));
23 counterDatas.Add(new CounterCreationData("calls / sec", "number of service calls per second.",
24 PerformanceCounterType.RateOfCountsPerSecond64));
25 counterDatas.Add(new CounterCreationData("errors total",
26 "number of errors returned form service to the client.",
27 PerformanceCounterType.NumberOfItems64));
28 counterDatas.Add(new CounterCreationData("errors / sec",
29 "number of errors returned form service to the client per second.",
30 PerformanceCounterType.RateOfCountsPerSecond64));
31 counterDatas.Add(new CounterCreationData("average processing time",
32 "average call processing time in milliseconds.",
33 PerformanceCounterType.AverageCount64));
34 counterDatas.Add(new CounterCreationData("average processing time base", "",
35 PerformanceCounterType.AverageBase));
36 counterDatas.Add(new CounterCreationData("Processing time latency",
37 "Processing time in milliseconds.",
38 PerformanceCounterType.NumberOfItems32));
39
40 PerformanceCounterCategory.Create("MyPerfCategory", "It is just for demonstration purpose!", PerformanceCounterCategoryType.MultiInstance, counterDatas);
41
42
43 }
44 catch (Exception ex)
45 {
46 Console.WriteLine("Error occurred: " + ex.ToString());
47 }
48 Console.ReadLine();
49 }
50 }
51}
52
3.客户端的代码使用两个timer在tick事件中生成的随机数做循环调用模拟当前的访问量,并且在每次调用的时候更新计数器,代码很简单。
1using System;
2using System.Collections.Generic;
3using System.ComponentModel;
4using System.Data;
5using System.Drawing;
6using System.Text;
7using System.Windows.Forms;
8using PerformanceCounterDemo.localhost;
9using ZZQ.Net.Demo;
10
11
12namespace PerformanceCounterDemo
13{
14 public partial class Demo : Form
15 {
16
17 public Demo()
18 {
19 InitializeComponent();
20 }
21
22 private void btnHello_Click(object sender, EventArgs e)
23 {
24 timer1.Enabled = true;
25 }
26
27
28
29 private void btnWelcome_Click(object sender, EventArgs e)
30 {
31 timer2.Enabled = true;
32 }
33
34 private void btnStop_Click(object sender, EventArgs e)
35 {
36
37 timer1.Enabled = false;
38 timer2.Enabled = false;
39 }
40 private void timer1_Tick(object sender, EventArgs e)
41 {
42 Random r = new Random();
43 int counter = r.Next(30);
44 CallHello(counter);
45
46 }
47
48 private void timer2_Tick(object sender, EventArgs e)
49 {
50 Random r = new Random();
51 int counter = r.Next(30);
52 CallWelcome(counter);
53 }
54
55
56 private void CallHello(int counter)
57 {
58 Service s = new Service();
59 string strResult = string.Empty;
60 for (int i = 0; i < counter; i++)
61 {
62 DateTime start = DateTime.Now;
63 strResult += "The " + i.ToString() + " time,return value is " + s.SayHelloTo("zzq" + i.ToString()) + "\r\n";
64 txtHello.Text = strResult;
65 TimeSpan span = DateTime.Now.Subtract(start);
66 PensPerfCounterManager.UpdatePerfCounters("MyPerfCategory", "SayHelloTo", span, true);
67
68 }
69 }
70 private void CallWelcome(int counter)
71 {
72 Service s = new Service();
73 string strResult = string.Empty;
74
75 for (int i = 0; i < counter; i++)
76 {
77 DateTime start = DateTime.Now;
78 strResult += "The " + i.ToString() + " time,return value is " + s.SayHelloTo("zzq" + i.ToString()) + "\r\n";
79 txtWelcome.Text = strResult;
80 PensPerfCounterManager.UpdatePerfCounters("MyPerfCategory", "SayWelcomeTo", start, true);
81 }
82 }
83
84 }
85}
2using System.Collections.Generic;
3using System.ComponentModel;
4using System.Data;
5using System.Drawing;
6using System.Text;
7using System.Windows.Forms;
8using PerformanceCounterDemo.localhost;
9using ZZQ.Net.Demo;
10
11
12namespace PerformanceCounterDemo
13{
14 public partial class Demo : Form
15 {
16
17 public Demo()
18 {
19 InitializeComponent();
20 }
21
22 private void btnHello_Click(object sender, EventArgs e)
23 {
24 timer1.Enabled = true;
25 }
26
27
28
29 private void btnWelcome_Click(object sender, EventArgs e)
30 {
31 timer2.Enabled = true;
32 }
33
34 private void btnStop_Click(object sender, EventArgs e)
35 {
36
37 timer1.Enabled = false;
38 timer2.Enabled = false;
39 }
40 private void timer1_Tick(object sender, EventArgs e)
41 {
42 Random r = new Random();
43 int counter = r.Next(30);
44 CallHello(counter);
45
46 }
47
48 private void timer2_Tick(object sender, EventArgs e)
49 {
50 Random r = new Random();
51 int counter = r.Next(30);
52 CallWelcome(counter);
53 }
54
55
56 private void CallHello(int counter)
57 {
58 Service s = new Service();
59 string strResult = string.Empty;
60 for (int i = 0; i < counter; i++)
61 {
62 DateTime start = DateTime.Now;
63 strResult += "The " + i.ToString() + " time,return value is " + s.SayHelloTo("zzq" + i.ToString()) + "\r\n";
64 txtHello.Text = strResult;
65 TimeSpan span = DateTime.Now.Subtract(start);
66 PensPerfCounterManager.UpdatePerfCounters("MyPerfCategory", "SayHelloTo", span, true);
67
68 }
69 }
70 private void CallWelcome(int counter)
71 {
72 Service s = new Service();
73 string strResult = string.Empty;
74
75 for (int i = 0; i < counter; i++)
76 {
77 DateTime start = DateTime.Now;
78 strResult += "The " + i.ToString() + " time,return value is " + s.SayHelloTo("zzq" + i.ToString()) + "\r\n";
79 txtWelcome.Text = strResult;
80 PensPerfCounterManager.UpdatePerfCounters("MyPerfCategory", "SayWelcomeTo", start, true);
81 }
82 }
83
84 }
85}
我的代码中UpdatePerfCounters方法的最后一个参数总是传的true,因为这两个web method太简单了,基本不会出错。^_^。实际用的时候会针对是否出现异常来决定是否更新和错误相关的计数器。
4.运行客户端的程序然后在运行里键入perfmon打开性能计数器管理窗口,找到MyPerfCategory性能对象,并且添加所有所有计数器的所有实例。
客户端演示效果图:
性能计数器效果图: