views:

290

answers:

4

I must be doing something very wrong here. I create a custom performance counter as follows:

string counterCategory = "Test Category";
string counterName = "Test Counter";

if (!PerformanceCounterCategory.Exists(counterCategory))
{
    Console.WriteLine("Creating Counters");

    CounterCreationDataCollection counterCreationDataCollection =
        new CounterCreationDataCollection();

    counterCreationDataCollection.Add(
        new CounterCreationData(counterName,
        "Description",
        PerformanceCounterType.NumberOfItems32)
    );

    PerformanceCounterCategory.Create(counterCategory,
        "My category description/Help",
        PerformanceCounterCategoryType.SingleInstance,
        counterCreationDataCollection);
}

The counter category and counter are created and viewable in performance monitor.

I then attempt to change the value of the counter

PerformanceCounter myCounter = 
    new PerformanceCounter(counterCategory, counterName, false);

for (int i = 0; i < 10; i++)
{
    Console.WriteLine("Setting to "+i);
    myCounter.RawValue = i;
    Thread.Sleep(200);
}

myCounter.Close();

However as I sit and watch the counter in performance monitor nothing happens, the value never changes.

So what am I doing wrong?

If I add a call to nextValue(), or rawValue() the value from that is returned as I expected but the Windows Performance Monitor still shows a flat line, e.g.

for (int i = 0; i < 10; i++)
{
    Console.WriteLine("Setting to "+i);
    myCounter.IncrementValue()
    Console.WriteLine("Next Value = "+myCounter.RawValue()); 
    Thread.Sleep(200);
}

Edit: I've found that if I close the performance monitor and then reopen it without deleting the counters, that suddenly it realises there's a new value. So the values are being set, and persisting, however Performance Monitor doesn't see the changes.

A: 

Are you sure your scale is at a level that will show the changes?

scottm
Yup, it's scaled from 0 to 20, so it should be obvious
blowdart
A: 

Your code looks good. From my working example the only difference is that I call the increment method after setting the RawValue.

PerformanceCounter myCounter = 
    new PerformanceCounter(counterCategory, counterName, false);

for (int i = 0; i < 10; i++)
{
    Console.WriteLine("Setting to "+i);
    myCounter.Increment();
    Thread.Sleep(200);
}

myCounter.Close();
Dejan
Nope, still a flat line I'm afraid, with Increment() and with setting the RawValue.
blowdart
Funny. Will look into it during lunch break.
Dejan
+1  A: 

Is it possible in the course of your testing that you changed the counter name? Your code doesn't verify that the category contains your counter - it only checks if the category exists, and if it does, it doesn't create the category.

If you've changed counter names since the first creation of the category, your new counter would not exist in the category and you might be missing a slight difference in the name of the counter when looking at it in Performance Monitor.

GBegen
It's a nice idea, but I'm deleting the category before I run this, so it will get recreated, and then both the category name and the counter name are held in strings used for both creation and opening the counter.
blowdart
Is this part of a larger project? When I took your code from the question and wrapped it in the `static void Main(string [] args)` method of a console project, it worked without modification. I needed to run it twice, once to create the category so I could find it in Performance Monitor, then a second time to watch the values change.
GBegen
This was in a console app (and for fun a web page to set raw values). I ended up closing performance monitor and opening it again and lo, it suddenly saw the changes. It may be that it doesn't like monitoring just after a counter is created.
blowdart
A: 

A follow up is in order. It appears, under Win7 anyway, that the performance monitor may not work as expected. When I wrote the test code I paused the application after creating the counters, in order to start the performance monitor. Once I let it continue the monitor never changed it's counters, despite the underlying counter being changed.

If I then quit the performance monitor and restarted it the last counter value in the test program would be shown, indicating that it was being set correctly. If I then ran the test program again, just changing values, performance monitor would finally pick up the changes.

So the code, as everyone indicated is correct, it was the Windows Performance monitor that was misbehaving.

Thank you all for your answers!

blowdart