Geekpedia Tutorials Home

Building a C# Chat Client and Server

Building a C# Chat Client and ServerA step by step tutorial teaching you how to create your own chat client and chat server easily in C#, for local networks or the Internet.

in C# Programming Tutorials

Getting Hard Drive Information

Getting Hard Drive InformationA C# tutorial showing you how to make use of WMI to extract information on disk drives, such as model, capacity, sectors and serial number.

in C# Programming Tutorials

UPS Shipping Calculator

UPS Shipping CalculatorThis tutorial will teach you how to calculate the shipping cost based on the weight, height, length and depth of the box, the distance and the UPS service type.

in PHP Programming Tutorials

Create Your Own Rich Text Editor

Create Your Own Rich Text EditorCreating a Rich Text Editor using JavaScript is easier to do than you might think, thanks to the support of modern browsers; this tutorial will walk you through it.

in JavaScript Programming Tutorials
Search
Tutorials
Programming Tutorials
IT Jobs
From CareerBuilder

Using Performance Counters in C#

The application we are building in this tutorial will make use of the Performance Counters made available by Windows. They allow us to retrieve CPU, memory and network usage among other counters.

On Saturday, June 30th 2007 at 12:16 AM
By Andrew Pociu (View Profile)
*****   (Rated 4.7 with 31 votes)
Contextual Ads
More C# Resources
Advertisement
Download this Visual Studio 2005 project Download this project (Visual Studio 2005)

The performance counters offered by the Windows Operating system can be accessed through Control Panel -> Administrative Tools -> Performance. But what's so great is that these performance counters can be easily queried from inside .NET Framework.

First of all, I want to make clear that the application we are building in this tutorial does not work with many of the performance counters that it lists, simply because there's too much code to write to make it adapt to different counter type, and we want to keep things simple. Fortunately it works with the most popular performance characters such as the processor usage and disk usage. Furthermore, since the graph that you see in the picture below is for fixed values of 0 to 100 (typical percentage values) it will not display correctly those performance counters that return values with a different range.

Let's start by creating the form:

Performance Counters Form

Three drop-down lists: lstCats, lstCounters, lstInstances are the ones that we populate with counter categories, counter names and counter instances. A start button btnStart is being used to enable the timer that reads the values. And speaking of that, don't forget to add the timer tmrCounter and set its Interval property to 1000 (1 second). This means the graph will update every second. I also added three labels lblValue, lblLow and lblHigh to display further information coming from the counter. The graph is drawn inside a PictureBox named picGraph that has a background image showing a scale. One more thing left: the actual PerformanceCounter object perfMain; you can find this on the Toolbox under Components.

Getting a list of available Performance Counters

In order to make this tutorial more useful we're not going to use a fixed, predefined list of counters, instead we're going to retrieve them dinamically from the user's operating system. This is particularly useful because the number of performance counters differ from system to system, depending on the hardware and software installed. Counters are divided into categories, thus first we need to retrieve these categories. We'll do this in the Load event of the form. But first let's place some using statements:


using System.Drawing.Drawing2D;

using System.Diagnostics;


And then initialize a variable we'll use to set the position of the graph line:


// Used to move the graph line

int graphIncrement = 0;


And now the Form1_Load event:


private void Form1_Load(object sender, EventArgs e)

{

    // Get a list of available performance counter categories

    PerformanceCounterCategory[] perfCounters = PerformanceCounterCategory.GetCategories();

    for (int i = 0; i < perfCounters.Length; i++)

    {

        // Add the category to the drop-down list

        lstCats.Items.Add(perfCounters[i].CategoryName);

    }

}


Now that we have the categories in the lstCats dropdown list, we should retrieve the counters depending on the selected category from the dropdown list. This will be done in the SelectedIndexChanged event of lstCats list, which fires each time a selection is made from the dropdown list:


private void lstCats_SelectedIndexChanged(object sender, EventArgs e)

{

    string[] instanceNames;

    System.Collections.ArrayList counters = new System.Collections.ArrayList();

    if (lstCats.SelectedIndex != -1)

    {

        System.Diagnostics.PerformanceCounterCategory mycat = new System.Diagnostics.PerformanceCounterCategory(this.lstCats.SelectedItem.ToString());

        // Remove the current contents of the list.

        this.lstCounters.Items.Clear();

        // Retrieve the counters.

        instanceNames = mycat.GetInstanceNames();

        if (instanceNames.Length == 0)

        {

            counters.AddRange(mycat.GetCounters());

        }

        else

        {

            for (int i = 0; i < instanceNames.Length; i++)

            {

                counters.AddRange(mycat.GetCounters(instanceNames[i]));

            }

        }

 

        // Add the retrieved counters to the list.

        foreach (System.Diagnostics.PerformanceCounter counter in counters)

        {

            this.lstCounters.Items.Add(counter.CounterName);

        }

    }

}


For the code above to work, don't forget to bind lstCats_SelectedIndexChanged to the SelectedIndexChanged event. The easiest way to do this in Visual Studio is to select the dropdown list, switch the Properties window to Events and double click the SelectedIndexChanged field.

We're not done yet with retrieving counters. Each counter has its own instances, which could reflect different values to be retrieved by that counter, some in percentages and others in various ranges. Some may not have any instances at all. _Total is a popular instance name which most of the time is used to retrieve the most popularly demanded type of value from that counter.
Each time a counter is selected we want to retrieve the list of possible instances:


private void lstCounters_SelectedIndexChanged(object sender, EventArgs e)

{

    // Clear the existing instance list

    lstInstances.Items.Clear();

    PerformanceCounterCategory perfCat = new PerformanceCounterCategory(lstCats.SelectedItem.ToString());

    string[] catInstances;

    catInstances = perfCat.GetInstanceNames();

    lstInstances.Items.Clear();

    foreach (string catInstance in catInstances)

    {

        lstInstances.Items.Add(catInstance);

    }

}


And now that the code for populating the instance list is in, we can write the code that starts the monitoring, and this is located in the Click even of btnStart:


private void btnStart_Click(object sender, EventArgs e)

{

    if (lstCats.SelectedIndex != -1 && lstCounters.SelectedIndex != -1 && lstInstances.SelectedIndex != -1)

    {

        // Clear the graph

        picGraph.Invalidate();

        graphIncrement = 0;

        perfMain.CategoryName = lstCats.SelectedItem.ToString();

        perfMain.CounterName = lstCounters.SelectedItem.ToString();

        perfMain.InstanceName = lstInstances.SelectedItem.ToString();

        tmrCounter.Start();

    }

    else

    {

        MessageBox.Show("Please select a category, counter and instance first.", "Selection needed", MessageBoxButtons.OK, MessageBoxIcon.Error);

    }

}


Aside from setting the properties for the counter object, we're starting the tmrCounter Timer object - it will be doing all the work from now on, so let's look at what's inside its Tick event:


private void tmrCounter_Tick(object sender, EventArgs e)

{

    float currVal;

    // Move to and get the latest value in the performance counter

    currVal = perfMain.NextValue();

    // Update the label with the value

    lblValue.Text = Math.Round(Convert.ToDouble(currVal.ToString()), 2) + "%";

    Graphics gfx = picGraph.CreateGraphics();

    Pen pn = new Pen(Color.Red, 1);

    gfx.DrawLine(pn, graphIncrement, 200, graphIncrement, 199 - (currVal * 2));

 

    graphIncrement += 2;

    if (graphIncrement > 500)

    {

        picGraph.Invalidate();

        graphIncrement = 0;

    }

}


Below is the application in action. There are many issues to address, including the PictureBox clearing when it gets invalidated and not all performance counters being properly scaled on the graph, but this is only a proof of concept application. One issue that you might experience though and which can easily be addressed is the "Access to the registry key 'Global' is denied." exception. This is caused on certain operating systems such as Windows Vista Ultimate when the account doesn't have administrative privileges and it's not allowed access to all the performance counters. After you compile the code, right click the application's executable, select Properties and in the Compatibility tab check the "Run this program as an administrator" checkbox.

Performance Counters Window

The full source code for the application is below:


using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using System.Drawing.Drawing2D;

using System.Diagnostics;

 

namespace PerformanceCounters

{

    public partial class Form1 : Form

    {

        // Used to move the graph line

        int graphIncrement = 0;

 

        public Form1()

        {

            InitializeComponent();

        }

 

        private void Form1_Load(object sender, EventArgs e)

        {

            // Get a list of available performance counter categories

            PerformanceCounterCategory[] perfCounters = PerformanceCounterCategory.GetCategories();

            for (int i = 0; i < perfCounters.Length; i++)

            {

                // Add the category to the drop-down list

                lstCats.Items.Add(perfCounters[i].CategoryName);

            }

        }

 

        private void tmrCounter_Tick(object sender, EventArgs e)

        {

            float currVal;

            // Move to and get the latest value in the performance counter

            currVal = perfMain.NextValue();

            // Update the label with the value

            lblValue.Text = Math.Round(Convert.ToDouble(currVal.ToString()), 2) + "%";

            Graphics gfx = picGraph.CreateGraphics();

            Pen pn = new Pen(Color.Red, 1);

            gfx.DrawLine(pn, graphIncrement, 200, graphIncrement, 199 - (currVal * 2));

 

            graphIncrement += 2;

            if (graphIncrement > 500)

            {

                picGraph.Invalidate();

                graphIncrement = 0;

            }

        }

 

        private void lstCats_SelectedIndexChanged(object sender, EventArgs e)

        {

            string[] instanceNames;

            System.Collections.ArrayList counters = new System.Collections.ArrayList();

            if (lstCats.SelectedIndex != -1)

            {

                System.Diagnostics.PerformanceCounterCategory mycat = new System.Diagnostics.PerformanceCounterCategory(this.lstCats.SelectedItem.ToString());

                // Remove the current contents of the list.

                this.lstCounters.Items.Clear();

                // Retrieve the counters.

                instanceNames = mycat.GetInstanceNames();

                if (instanceNames.Length == 0)

                {

                    counters.AddRange(mycat.GetCounters());

                }

                else

                {

                    for (int i = 0; i < instanceNames.Length; i++)

                    {

                        counters.AddRange(mycat.GetCounters(instanceNames[i]));

                    }

                }

 

                // Add the retrieved counters to the list.

                foreach (System.Diagnostics.PerformanceCounter counter in counters)

                {

                    this.lstCounters.Items.Add(counter.CounterName);

                }

            }

        }

 

        private void btnStart_Click(object sender, EventArgs e)

        {

            if (lstCats.SelectedIndex != -1 && lstCounters.SelectedIndex != -1 && lstInstances.SelectedIndex != -1)

            {

                // Clear the graph

                picGraph.Invalidate();

                graphIncrement = 0;

                perfMain.CategoryName = lstCats.SelectedItem.ToString();

                perfMain.CounterName = lstCounters.SelectedItem.ToString();

                perfMain.InstanceName = lstInstances.SelectedItem.ToString();

                tmrCounter.Start();

            }

            else

            {

                MessageBox.Show("Please select a category, counter and instance first.", "Selection needed", MessageBoxButtons.OK, MessageBoxIcon.Error);

            }

        }

 

        private void lstCounters_SelectedIndexChanged(object sender, EventArgs e)

        {

            // Clear the existing instance list

            lstInstances.Items.Clear();

            PerformanceCounterCategory perfCat = new PerformanceCounterCategory(lstCats.SelectedItem.ToString());

            string[] catInstances;

            catInstances = perfCat.GetInstanceNames();

            lstInstances.Items.Clear();

            foreach (string catInstance in catInstances)

            {

                lstInstances.Items.Add(catInstance);

            }

        }

    }

}

Digg Digg It!     Del.icio.us Del.icio.us     Reddit Reddit     StumbleUpon StumbleIt     Newsvine Newsvine     Furl Furl     BlinkList BlinkList

Rate Rate this tutorial
Comment Current Comments
by haroon shahzad on Thursday, May 15th 2008 at 07:47 AM

Good code!
Thanks

by mahesh kulkarni on Tuesday, June 24th 2008 at 03:31 AM

I HAVE TIRED THSI AMPLE CODE IT NOT GIVING ANY ERROR BUT IT IS NOT SHOWING THE GRAPH.ALSO TELL ME ABOUT WHIC COUTER NAME AND CATAGORY NAME I HAVE TO SET INITIALY.

by mahesh kulkarni on Tuesday, June 24th 2008 at 03:31 AM

I HAVE TIRED THSI AMPLE CODE IT NOT GIVING ANY ERROR BUT IT IS NOT SHOWING THE GRAPH.ALSO TELL ME ABOUT WHIC COUTER NAME AND CATAGORY NAME I HAVE TO SET INITIALY.

by mahesh kulkarni on Tuesday, June 24th 2008 at 03:31 AM

I HAVE TIRED THSI AMPLE CODE IT NOT GIVING ANY ERROR BUT IT IS NOT SHOWING THE GRAPH.ALSO TELL ME ABOUT WHIC COUTER NAME AND CATAGORY NAME I HAVE TO SET INITIALY.

by Chakradhar on Tuesday, July 22nd 2008 at 12:37 PM

Its nice to see the code.I am devloping the same counters cpu memory and battery life for windows mobile.Can this code be helpful.Can i get cpu usage from this?
Chakradhar

by Chakradhar on Tuesday, July 22nd 2008 at 12:37 PM

Its nice to see the code.I am devloping the same counters cpu memory and battery life for windows mobile.Can this code be helpful.Can i get cpu usage from this?
Chakradhar

by oduy on Friday, February 20th 2009 at 07:59 PM

Good code
it is very nice, but there are some problem with Catgory Name: .NET Network CRL it is not work ,if any one has the soultion for this problem plz submit on sits
Thanks

by oduy on Friday, February 20th 2009 at 08:00 PM

Good code
it is very nice, but there are some problem with Catgory Name: .NET Network CRL it is not work ,if any one has the soultion for this problem plz submit on sits
Thanks

by minhquang on Wednesday, September 23rd 2009 at 03:35 AM

this code is very good
thank's

by Ta Xuan Truong on Thursday, December 10th 2009 at 11:45 AM

That's great !

Thank you for your sharing.

by Ta Xuan Truong on Thursday, December 10th 2009 at 11:45 AM

That's great !

Thank you for your sharing.

by markf4 on Monday, January 4th 2010 at 06:44 AM

very good!
I've tried in on my webservice in

by Jeff on Tuesday, May 18th 2010 at 12:52 PM

Could you please send me the entire solution? I have tried your code, but it doesn't work.

Thanks.

by Jeff on Tuesday, May 18th 2010 at 12:52 PM

Could you please send me the entire solution? I have tried your code, but it doesn't work.

Thanks.

by Quick Guide on Thursday, May 27th 2010 at 02:54 AM

I Would be using this for KPI Solution Program...where I need to monitor progress of KPI's of personnel...will it work with the graph that was shown in this sample template?

Using C#.NET 2005 on XP -OR-
Using C#.NET (Visual Studio 2010 Ultimate)

by CY on Monday, June 21st 2010 at 07:48 PM

Good stuff.

by CY on Monday, June 21st 2010 at 07:48 PM

Good stuff.

by Sachet on Thursday, July 1st 2010 at 06:17 AM

As a part of the application which m making..i want to calculate the total data transfer between particular interval of time..ie the total amont of download n uploaded data..by the user..cn any1 provide me with d code to calculate the total data transfer in asp.net for web application

by karthik on Saturday, November 13th 2010 at 04:50 AM

could u plz send the code of entire solution ?

by priya on Wednesday, January 5th 2011 at 04:47 AM

this code doesn't give any idea about form design. pls mention it.

by hussien on Monday, March 7th 2011 at 09:08 AM

please help me for source code on c# for the network monitoring sytsem
im student on the last years
thanks

by apply for a credit card on Monday, December 12th 2011 at 05:13 AM

i need more explanation on remember me checkbox using cookies and Wonderful! I am such a big fan of the blue ridge mountains. There is nothing better then this beauty.and also i want to known that how to assign cookies in one page and get cookies from Another page, but those things r done only in JAVASCRIPT.. [ASP.NET] Help Me...

by Phen375 on Monday, December 19th 2011 at 06:01 PM

Your personal know-how and kindness in maneuvering every part was tremendous. I am not sure what I would've done if I hadn't encountered such a solution like this. I'm able to at this time look ahead to my future. Thanks a lot so much for the specialized and result oriented help. I won't hesitate to endorse the blog to anybody who desires assistance on this topic.

by GenF20 Plus on Monday, December 19th 2011 at 06:02 PM

Your personal know-how and kindness in maneuvering every part was tremendous. I am not sure what I would've done if I hadn't encountered such a solution like this. I'm able to at this time look ahead to my future. Thanks a lot so much for the specialized and result oriented help. I won't hesitate to endorse the blog to anybody who desires assistance on this topic.

by GenFX on Monday, December 19th 2011 at 06:03 PM

Your personal know-how and kindness in maneuvering every part was tremendous. I am not sure what I would've done if I hadn't encountered such a solution like this. I'm able to at this time look ahead to my future. Thanks a lot so much for the specialized and result oriented help. I won't hesitate to endorse the blog to anybody who desires assistance on this topic.

by Teeth Whitening Reviews on Tuesday, December 20th 2011 at 01:40 AM

I truly wanted to write a quick message to thank you for some of the splendid points you are showing at this website. My long internet investigation has at the end been compensated with sensible facts and techniques to share with my family and friends.

by Human Growth Hormone on Tuesday, December 20th 2011 at 01:40 AM

I truly wanted to write a quick message to thank you for some of the splendid points you are showing at this website. My long internet investigation has at the end been compensated with sensible facts and techniques to share with my family and friends.

by Best Diet Pills on Tuesday, December 20th 2011 at 01:46 AM

I would believe that we visitors are truly blessed to dwell in a wonderful network with many wonderful professionals with very beneficial hints. I feel extremely privileged to have seen the web pages and look forward to many more pleasurable times reading here. Thank you once again for everything.

by HGH Advanced on Tuesday, December 20th 2011 at 01:53 AM

I would believe that we visitors are truly blessed to dwell in a wonderful network with many wonderful professionals with very beneficial hints. I feel extremely privileged to have seen the web pages and look forward to many more pleasurable times reading here. Thank you once again for everything.

by Dental White on Tuesday, December 20th 2011 at 01:56 AM


Thanks so much for providing individuals with an extremely remarkable possiblity to read critical reviews from this web site. It is always so beneficial plus jam-packed with a great time for me personally and my office friends to search the blog at the least three times in one week to see the fresh secrets you will have.

by Pure Acai Berry Max on Tuesday, December 20th 2011 at 01:59 AM


Thanks so much for providing individuals with an extremely remarkable possiblity to read critical reviews from this web site. It is always so beneficial plus jam-packed with a great time for me personally and my office friends to search the blog at the least three times in one week to see the fresh secrets you will have.

by Ultimate Maqui Berry on Tuesday, December 20th 2011 at 02:02 AM

I am just always happy with your good tips and hints served by you. Some 1 areas in this article are undeniably the finest I've had.

by Proactol Plus on Tuesday, December 20th 2011 at 02:04 AM

I am just always happy with your good tips and hints served by you. Some 1 areas in this article are undeniably the finest I've had.

by Provacyl on Tuesday, December 20th 2011 at 02:09 AM

I am just always happy with your good tips and hints served by you. Some 1 areas in this article are undeniably the finest I've had.

by Nuratrim on Tuesday, December 20th 2011 at 02:13 AM

Thanks a lot for providing individuals with remarkably special possiblity to read critical reviews from this web site. It can be very kind plus packed with a great time for me personally and my office mates to visit your site no less than three times weekly to study the newest tips you have.

by Capsiplex on Tuesday, December 20th 2011 at 02:21 AM

Thanks a lot for providing individuals with remarkably special possiblity to read critical reviews from this web site. It can be very kind plus packed with a great time for me personally and my office mates to visit your site no less than three times weekly to study the newest tips you have.

by on Saturday, January 14th 2012 at 01:21 AM

Once you have recreated the problem and captured these steps, you can save them to a file and send it to your support person, who can then open it up and view

by GD Poker on Sunday, January 22nd 2012 at 03:34 PM

Hey very cool website!! Guy .. Excellent .. Wonderful .. I will bookmark your website and take the feeds additionally¡KI am glad to seek out a lot of helpful information right here in the put up, we need develop more strategies on this regard, thanks for sharing. . . . . .

by migz on Monday, February 20th 2012 at 02:58 AM

hey dude it cool

by kid tents on Thursday, April 12th 2012 at 05:48 AM

Much appreciated for the information and share!

by Bruno on Tuesday, May 29th 2012 at 02:11 PM

Hi there,

How would that work if I want to monitor the performance of a remote server?

by Bruno on Tuesday, May 29th 2012 at 02:11 PM

Hi there,

How would that work if I want to monitor the performance of a remote server?

by medical emergency kit supplies on Thursday, October 25th 2012 at 12:55 AM

information right here in the put up, we need develop more strategies on this regard, thanks for sharing. .

by on Thursday, November 1st 2012 at 05:35 AM

the put up, we need develop more strategies on this regard, thanks for sharing. .


Comment Comment on this tutorial
Name: Email:
Message:
Comment Related Tutorials
There are no related tutorials.

Comment Related Source Code
There is no related source code.

Jobs C# Job Search
My skills include:
Enter a City:

Select a State:


Advanced Search >>
Ads

From the creators of Geekpedia, a revolutionary new coupon website!

BargainEZ has coupons codes, printable coupons, bargains and it is the leading source of Passbook coupons for iPhone and iPod touch devices.

Coupons
Discover Geekpedia
Other Resources