The PerformanceCounterCategory class
has both a constructor and a Create method.
Both create a custom performance counter category.
The only difference that I can see from the documentation is that the create method also adds performance counters in the category it creates.
However when I tested creating a custom category with the create
method I could not after that associate a performance counter with it.
PerformanceCounterCategory myCat = new PerformanceCounterCategory("test");
PerformanceCounter counter = new PerformanceCounter(myCat.CategoryName, "asd", Process.GetCurrentProcess().ProcessName);
//The second line throws an System.InvalidOperationException: 'Category does not exist.' exception
While if I use the "Create" method no exception is thrown (ignore the name of the counter for this question).
I did not see anything in the documentation that would suggest such a behaviour.
Is this intentional or am I missing something when using the constructor
? In addition what are the differences between using the constructor and the create method?
A common problem in using Windows Performance Counters is the desire to create them on-the-fly as needed, with each new run creating whatever counters are appropriate for that version of the code.
Windows Performance Counters were designed and implemented long, long, long ago, and as such, are intended to be registered during some kind of installation process. Back then, all software of any significance went through a user-initiated installation process on first install and during any updates. In fact, the act of registering a performance counter category and its corresponding counters requires fairly high privileges (you can't do it under IIS with the default privileges, for example). The system also doesn't allow on-the-fly changes to counters anyway. This does have the advantage that clients can query the available counters and know that they're not going to change while they're gathering them (at least while the associated process is running). If you want something that can change dynamically, you'll have to roll your own (it's not that hard, unless you want them to show up in the Windows performance monitor).
So, proper use of performance counters is as follows: during installation, to create a performance counter category and the corresponding counters:
PerformanceCounterCategory.Create ("My category", "Category Description", PerformanceCounterCategoryType.SingleInstance, counterCreationDataCollection /* <--premade, hardcoded list of counters */);
and during a normal execution, to connect to a performance counter category previously registered using Create
as above:
private static PerformanceCounterCategory _MyCategory = new PerformanceCounterCategory("My category"); // connect to the previously-registered performance counter category so we can set counter values
The constructor that takes a machine name is to act as a client to gather statistics from another machine.
Also keep in mind that there is a limit on how many performance counters you can have in your program, and that special network privileges are required to query the values as well. The limit depends on the size of the counter names and help, and their values, and it's very difficult to change, so you'll probably want to avoid hitting that (from experience I can tell you that when you do, various counters past the limit will appear to all have the same value). Despite the limitations, they can be quite useful in many circumstances.