2011-10-03 7 views
7

Ciao Sto cercando di creare un contatore delle prestazioni personalizzato per l'utilizzo in perfmon. Il seguente codice funziona piuttosto bene, tuttavia ho un problema.in C#/perfmon

Con questa soluzione ho un timer che aggiorna il valore del contatore delle prestazioni, tuttavia non mi piacerebbe dover eseguire questo eseguibile per ottenere i dati di cui ho bisogno . Vorrei semplicemente poter installare il contatore come una cosa sola e poi avere una query perfmon per i dati (come con tutti i contatori preinstallati).

Come posso ottenere questo risultato?

using System; 
using System.Diagnostics; 
using System.Net.NetworkInformation; 

namespace PerfCounter 
{ 
class PerfCounter 
{ 
    private const String categoryName = "Custom category"; 
    private const String counterName = "Total bytes received"; 
    private const String categoryHelp = "A category for custom performance counters"; 
    private const String counterHelp = "Total bytes received on network interface"; 
    private const String lanName = "Local Area Connection"; // change this to match your network connection 
    private const int sampleRateInMillis = 1000; 
    private const int numberofSamples = 100; 

    private static NetworkInterface lan = null; 
    private static PerformanceCounter perfCounter; 

    static void Main(string[] args) 
    { 
     setupLAN(); 
     setupCategory(); 
     createCounters(); 
     updatePerfCounters(); 
    } 

    private static void setupCategory() 
    { 
     if (!PerformanceCounterCategory.Exists(categoryName)) 
     { 
      CounterCreationDataCollection counterCreationDataCollection = new CounterCreationDataCollection(); 
      CounterCreationData totalBytesReceived = new CounterCreationData(); 
      totalBytesReceived.CounterType = PerformanceCounterType.NumberOfItems64; 
      totalBytesReceived.CounterName = counterName; 
      counterCreationDataCollection.Add(totalBytesReceived); 
      PerformanceCounterCategory.Create(categoryName, categoryHelp, PerformanceCounterCategoryType.MultiInstance, counterCreationDataCollection); 
     } 
     else 
      Console.WriteLine("Category {0} exists", categoryName); 
    } 

    private static void createCounters() { 
     perfCounter = new PerformanceCounter(categoryName, counterName, false); 
     perfCounter.RawValue = getTotalBytesReceived(); 
    } 

    private static long getTotalBytesReceived() 
    { 
     return lan.GetIPv4Statistics().BytesReceived; 
    } 

    private static void setupLAN() 
    { 
     NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces(); 
     foreach (NetworkInterface networkInterface in interfaces) 
     { 
      if (networkInterface.Name.Equals(lanName)) 
       lan = networkInterface; 
     } 
    } 
    private static void updatePerfCounters() 
    { 
     for (int i = 0; i < numberofSamples; i++) 
     { 
      perfCounter.RawValue = getTotalBytesReceived(); 
      Console.WriteLine("perfCounter.RawValue = {0}", perfCounter.RawValue); 
      System.Threading.Thread.Sleep(sampleRateInMillis); 
     } 
    } 
} 

}

risposta

6

In Win32, contatori prestazioni di lavoro avendo PerfMon caricare un DLL che fornisce i valori del contatore.

In .NET, questa DLL è uno stub che utilizza la memoria condivisa per comunicare con un processo .NET in esecuzione. Il processo invia periodicamente nuovi valori al blocco di memoria condivisa e la DLL li rende disponibili come contatori delle prestazioni.

Quindi, in pratica, probabilmente si dovrà implementare la DLL del contatore delle prestazioni nel codice nativo, poiché i contatori delle prestazioni .NET presuppongono che sia in esecuzione un processo.