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 / June 2006

Tip: Looking for answers? Try searching our database.

Problem of refresh with PerformanceCounter and failover.

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Lionel Schiepers - 21 Jun 2006 12:36 GMT
We have a multithreaded service written in .NET 2.0 that is running 24h/24.
This service checks nearly 250 another servers to log statisticals data
acquired via WMI, SNMP, PerformanceCounter...

We use XOsoft for the fail over of our SQL Server databases (active, passive
but the clients are always using the same name to connect to the elected
active server) but we always have problems when the active server change
because the PerformanceCounter objects use a cache located to the class
PerformanceCounterLib internal to the .NET framework. This cache contains
the categories available for each server name. Because the servers are not
identical, the categories of a server cannot be reused for the other one and
we catch these exceptions after a fail over.

[2006/06/21 13:05:16.1935] Pdh Failed for xxx..bvdep.net
System.InvalidOperationException: Could not Read Category Index: 3616.
  at System.Diagnostics.CategorySample..ctor(Byte[] data, CategoryEntry
entry, PerformanceCounterLib library)
  at System.Diagnostics.PerformanceCounterLib.GetCategorySample(String
category)
  at System.Diagnostics.PerformanceCounterLib.GetCategorySample(String
machine, String category)
  at System.Diagnostics.PerformanceCounter.NextSample()
  at ServerPatrol.Agent.Components.Specialized.Pdh.Invoke(ResultPipeline
results, TargetDTO target, String& resultDescription)

It exists the method PerformanceCounter.CloseSharedResources() that clears
the cache but for all servers which is not interesting for us because we
have all the time between 1.000 and 3.000 open performance counters
dispatched to ~250 servers. I'm not even sure it's possible because the
service is always running between 10 and 60 threads at the same time and the
implementation of CloseSharedResources doesn't seem to be thread safe.

Is there any tricks to correct this kind of problem?

I have two solutions but I prefer not to use them until a better one.

1. Put the PerformanceCounters associated to a server in a dedicated
application domain. That way, I can call CloseSharedResources without
loosing the data of the other servers. I don't like this solution because:
   - I don't want to manage the lifetime of my objects between the
application domain
   - I don't want an application with ~250 application domains.
   - Debugging is harder.

2. Directly removing the concerned cached entries via reflection (because
the class is internal). I used Reflector to write the following code but I
don't like this solution because the internal implementation could change
between different version of the .NET Framework.

   System.Reflection.Assembly assembly =
System.Reflection.Assembly.GetAssembly(typeof(PerformanceCounter));
   Type type =
assembly.GetType("System.Diagnostics.PerformanceCounterLib");
   System.Reflection.FieldInfo fi = type.GetField(
       "libraryTable",
       System.Reflection.BindingFlags.Static |
System.Reflection.BindingFlags.NonPublic);

   Hashtable dictionary = fi.GetValue(null) as Hashtable;
   if (null == dictionary)
       return;
   System.Globalization.CultureInfo culture = new
System.Globalization.CultureInfo(9);
   string key =
server.ToLower(System.Globalization.CultureInfo.InvariantCulture) + ":" +
culture.LCID.ToString("X3",
System.Globalization.CultureInfo.InvariantCulture);
   object o = dictionary[key];
   if (null != o)
   {
       System.Reflection.MethodInfo mi = o.GetType().GetMethod("Close",
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.NonPublic);
       mi.Invoke(o, new object[0]);
       dictionary.Remove(key);
   }

Thanks in advance.

Lionel Schiepers (ls at bvdep.com),
Bureau van Dijk Electronic Publishing
Belgium.
Lionel Schiepers - 21 Jun 2006 12:46 GMT
I forgot to mention that I recreate the performance counter when I catch an
exception.

Lionel Schiepers

> We have a multithreaded service written in .NET 2.0 that is running
> 24h/24. This service checks nearly 250 another servers to log statisticals
[quoted text clipped - 78 lines]
> Bureau van Dijk Electronic Publishing
> Belgium.

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.