Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / New Users / July 2005

Tip: Looking for answers? Try searching our database.

Bug: PerformanceCounterCategory.Delete removes entire registry key

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Steve Townsend - 30 Jun 2005 20:20 GMT
I am attempting to instrument several existing Windows service applications
(written in C#) using the PerformanceCounter* classes in .Net FW 1.1 SP1.  
Each service must dynamically add its required counters based on
configuration metadata from SQL Server using the service name as the
Category, and to this end I have the following code snippet:

        /// <summary>
        /// This method exports the statistics for this process to PerfMon.  This
must be called
        /// at the end or process initialization so that all statistics for the
process are
        /// registered.
        /// If this is called multiple times the existing data structure is
replaced by an
        /// updated version.  This allows, if rather clumsily, counters to be
added after
        /// AppManager has completed process initialization.
        /// </summary>
        /// <returns></returns>
        public void ExportStatistics()
        {
            lock (this)
            {
                // Remove any hanging or previously-created category information
                if (PerformanceCounterCategory.Exists( _perfMonCategoryName ))
                {
                    PerformanceCounterCategory.Delete( _perfMonCategoryName );
                }

... boring details of actual counter setup omitted.

The first call to this method works OK - registry keys named "Linkage" and
"Performance" are added to
HKLM\System\CurrentControlSet\Services\<category-name>, which already exists
because that's the service which is going to publish the counters.

Now, when a revised list of counters needs to be published, the entire
category has to be discarded and recreated, per the following text in MSDN's
description of PerformanceCounterCategory.Delete:

"Remarks
You can delete only custom performance counter categories from the system.
You cannot delete a counter from a category. To do so, delete the category
and recreate the category with the counters you want to retain."

At this point the code snippet above finds .Exists=True and calls .Delete.  
I walked through this in the debugger and the entire registry key at
HKLM\System\CurrentControlSet\Services\<category-name/service-name> is
deleted by this method call.  This seems like a bug, because it's impossible
under this behaviour to instrument a .Net service with revised Performance
Counters without requiring a full reinstall.  This is since my service (and
any other I have ever known) stores its configuration bootstrap data under a
"Parameters" subkey of this now-deleted service Registry placeholder.

Is there a fix for this available or planned?  I am sure there are hacks I
could use to get around this (e.g. use a name mapping to put the Category
info in a different place in the Registry from the rest of the service
configuration), but the current behaviour seems clearly incorrect.

Signature

Steve Townsend
Lava Trading

David Browne - 30 Jun 2005 21:20 GMT
>I am attempting to instrument several existing Windows service applications
> (written in C#) using the PerformanceCounter* classes in .Net FW 1.1 SP1.
[quoted text clipped - 59 lines]
> info in a different place in the Registry from the rest of the service
> configuration), but the current behaviour seems clearly incorrect.

I believe this behavior is changed in .NET 2.0 to delete only the Linkage
and Performance subkeys when the service key has other information in it
too.

David
Steve Townsend - 01 Jul 2005 14:37 GMT
That's good news, thanks.

I worked around this by using a different name for the category and the
service.  This is fine for now.

Now I'm hitting another problem.  After I Delete the category and re-Create
it, I then add the new counters using code as follows:

                // Remove any hanging or previously-created category information
                if (PerformanceCounterCategory.Exists( _perfMonCategoryName ))
                {
                    PerformanceCounterCategory.Delete( _perfMonCategoryName );
                }

                if (_perfMonCategory != null)
                {
                    ApplicationLog.Log( LogType.INFO, 0,
                                        "PerfMon Statistics are being replaced for " +
                                        _perfMonCategoryName);

                    foreach (PerformanceCounter pc in _perfMonData)
                    {
                        pc.Close();
                    }
                    PerformanceCounter.CloseSharedResources();

                    _perfMonData.Clear();
                }

                // Register the current process with PerfMon as a new category of
counters, with
                // one entry in a list of counters per Statistic for the process
                CounterCreationDataCollection newCounters = new
CounterCreationDataCollection();
   
                foreach (Statistic st in _statistics)
                {
                    CounterCreationData newCounter = new CounterCreationData(st.PerfMonName,
                                                                            st.PerfMonName,
                                                                            PerformanceCounterType.NumberOfItems32 );
                    newCounters.Add(newCounter);
                }
   
                _perfMonCategory = PerformanceCounterCategory.Create(
_perfMonCategoryName,
                                                                     ColorPaletteHelpString,
                                                                     newCounters);

                // Export the initial values for each counter
                foreach (Statistic st in _statistics)
                {
                    PerformanceCounter newData = new PerformanceCounter(
_perfMonCategoryName,
                                                                        st.Name,
                                                                        false );    // writable
                    ApplicationLog.Log( LogType.INFO, 0,
                        "PerfMon counter:" +
                        newData.CounterType + " " + newData.CounterHelp);

                    newData.RawValue = st.iValue;
                    st.Counter = newData;

                    _perfMonData.Add( newData );
                }
            }

In the debugger, the categoryHelp on _perfMonCategory shows up as null
although I am passing in a string ColorPaletteHelpString.  In addition, the
Log call to dump newData.CounterType and newData.CounterHelp fails with
exception "Category does not exist", although I can see it in the debugger
after the .Create call just above.

I am beginning to suspect that this area of .Net 1.1 is what is sometimes
referred to as  a "bug farm".  Is this one also expected to be fixed in .Net
2.0?  Are there any other known bugs I need to look out for?

Another comment - it looks to me like the PerformanceCounterCategory class
may use a single named mutex "netfxperf.1.0" to control access to all .Net
custom counters.  The SWI team would probably be interested in this, since
these are trivial to squat on and deny access to legitimate users, without
proper security controls.

Signature

Steve Townsend
Lava Trading

> >I am attempting to instrument several existing Windows service applications
> > (written in C#) using the PerformanceCounter* classes in .Net FW 1.1 SP1.
[quoted text clipped - 65 lines]
>
> David
Steve Townsend - 06 Jul 2005 15:29 GMT
OK, I have a red face.  There's a bug in the code I posted here - once I
fixed this the code is working better and publishing data OK.  The exception
text is misleading (it's the counter name on PerformanceCounter.Create that's
at fault, not the category) but I still could have checked further.  When I
ran under .Net 2.0, the Fwk provides a better exception, and the fix was then
trivial.

Thanks for your help.
Signature

Steve Townsend
Lava Trading

> That's good news, thanks.
>
[quoted text clipped - 147 lines]
> >
> > David

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.