2009-06-27 9 views
6

VS 2005, C# 2.0, .NET 2.0/3.0, Win2003Installazione di un'istanza totale per i contatori delle prestazioni

Sto cercando di installare una serie di contatori delle prestazioni per un MultiInstance. Ho notato che alcune categorie di contatori delle prestazioni del sistema riescono a mantenere in vita uno "totale" anche quando non ci sono altre istanze. Le app ASP.NET 2.0.50727 sono un esempio.

Quindi ho cercato di duplicare questo. Ho creato la seguente routine in una classe Installer che aggiungo a un'azione personalizzata in un progetto di installazione.

public override void Install(System.Collections.IDictionary stateSaver) 
{ 
    //Debugger.Break(); 
    CounterCreationData data = new CounterCreationData("ZCounter", "ZCtrHelp", PerformanceCounterType.NumberOfItems32); 
    PerformanceCounterCategory.Create("ZCategory", "ZCatHelp", PerformanceCounterCategoryType.MultiInstance, new CounterCreationDataCollection(new CounterCreationData[] { data })); 
    PerformanceCounter counter = new PerformanceCounter(); 
    counter.CategoryName = "ZCategory"; 
    counter.CounterName = "ZCounter"; 
    counter.InstanceName = "ZTotal"; 
    counter.InstanceLifetime = PerformanceCounterInstanceLifetime.Global; 
    counter.ReadOnly = false; 
    counter.RawValue = 0; 
    base.Install(stateSaver); 
} 

Se togliere il commento alla linea di Debugger.Break(), e passo attraverso, posso vedere il contatore è effettivamente creato con il nome di istanza a destra, e Visual Studio Server Explorer mostra l'istanza con l'InstanceLifetime impostato su Globale. Non chiamo il metodo RemoveInstance() nel programma di installazione.

Tuttavia, pochi secondi dopo il completamento del programma di installazione, tale istanza scompare dal Performance Monitor e da VS Server Explorer. Come faccio a farlo bastone? O posso?

risposta

7

Alcuni codici devono mantenere attivamente il contatore. In tutti i casi a cui puoi pensare, come ASP.Net, c'è un servizio che tiene il contatore in su.

Come non si è soddisfatti di avere un'istanza _Total attivo solo mentre alcuni esempio della vostra applicazione è in esecuzione, è necessario scrivere del codice che manterrà le prestazioni contatore al di fuori della vostra applicazione. Non c'è magia.

È possibile scrivere un piccolo servizio che richiede il monitoraggio. Ciò manterrà il contatore totale. Devi decidere un regime di aggiornamento. Il modo più semplice è che ogni istanza della tua app aggiorni entrambe le istanze (la loro e _Totale).

Un po 'di background sui contatori delle prestazioni: la cosa principale da capire è che in genere esiste un'area di memoria condivisa condivisa tra i processi che viene aggiornata tramite operazioni interbloccate. Uno strumento come PerfMon (o qualsiasi altra app) finisce per connettersi alla regione di memoria condivisa per ottenere i valori correnti. Quindi alcuni processi devono avere quell'area di memoria condivisa aperta e di proprietà. Quindi perché hai bisogno di codice in esecuzione.PerfMon non sta creando l'istanza _Total per te (ha alcune combinazioni piuttosto contorte di contatori che consentono medie e tassi, ma non una somma per creare un'istanza di riepilogo).

+0

Ritengo che questa sia la risposta giusta alla mia domanda. mark is gone; non riesco a selezionarlo come risposta corretta Sapevo che PerfMon non stava creando il contatore _Total, ma non mi era chiaro che c'era sempre un servizio che manteneva il totale contro il vivo. "PerformanceCounterInstanceLifetime.Global" suggerisce che dovrebbe farlo; altrimenti, qual è il punto di quel nome? BTW, non sono affatto contrario a scrivere qualsiasi quantità di codice, servizi o qualsiasi altra cosa. Solo non sapevo che era come si faceva. Mi risento di essere considerato un programmatore pigro. –

0

Provare a creare la categoria con "PerformanceCounterCategoryType.SingleInstance".

+0

Probabilmente potrei, ma ciò vanifica lo scopo di avere un'istanza "Totale" (utilizzata per aggregrare i risultati di tutte le altre istanze). So che è possibile; come ho detto, ASP.NET lo sta facendo in qualche modo. Forse usa qualche altro processo per mantenere l'istanza "__Total__" nel contatore? –

+0

Non so della cosa "altro processo", ma sarei interessato se c'è una tale bestia. Vorrei creare il contatore SingleInstance e ogni volta che aggiorno MultiInstance/istanza specifica, uno aggiornerei SingleInstance/global-one con lo stesso valore. Cioè fare la "aggregazione" manualmente. –

+0

Siamo spiacenti di non aver visto questo commento prima. Due problemi: 1) SingleInstance * category * significa che non ci sono istanze con nome. 2) So che posso aggiornare più istanze (una istanza "totale" e una "processo") - non è un mio problema. Il problema è "come faccio a MANTENERE l'istanza" totale "della categoria MultipleInstance mostrata nella lista del contatore perf quando non ci sono istanze in esecuzione? –

0

Solo un suggerimento, ma provare a fare

Counter.ReadOnly = true; 

il primo passaggio attraverso e solo l'impostazione su False quando è necessario incrementare il contatore.

E anche se si effettua la sola lettura del contatore chiaramente bisogno di commentare la riga:

Counter.RawData = 0; 

credo il suo set a 0 per default il primo passaggio, comunque.

Spero che questo aiuti ...

+0

Ci proverò e ti faccio sapere oggi –

+0

Mike: the test non è riuscito. Se avesse funzionato, ci sarebbe stata una singola istanza denominata "ZTotal" in Performance Monitor per quella categoria e contatore, e non c'è. –

1

per quanto ne so una Performance categoria contatore globale resterà in vita finché ogni processo ha una maniglia attiva riferimento di esso. I contatori di sistema ottengono ciò mantenendo un handle sull'istanza del contatore totale in alcuni servizi.