2008-11-09 7 views
35

Je travaille sur un programme en arrière-plan qui fonctionnera depuis longtemps, et j'ai un programme de journalisation externe (SmartInspect) que je veux régulièrement alimenter avec certaines valeurs, pour le surveiller en temps réel lors du débogage. Je sais que je peux simplement lancer plusieurs programmes, comme le Gestionnaire des tâches, ou IARSN TaskInfo, mais je voudrais garder tout dans mon propre programme pour cela, car je veux aussi ajouter des règles simples comme si le Le programme utilise plus de X% CPU, signalez ceci dans le journal.Un programme C# peut-il mesurer sa propre utilisation du CPU?

J'ai un fil d'arrière-plan qui alimente périodiquement des statistiques à SmartInspect, comme la consommation de mémoire, jeu de travail, etc.

Est-il possible pour ce thread pour obtenir une mesure assez précise de la quantité des ressources CPU de l'ordinateur ça consomme? Le programme principal est une application monothread (à part le thread de surveillance qui enregistre les statistiques), donc si une technique est limitée à combien un seul thread utilise alors ce serait bien aussi.

J'ai trouvé quelques entrées liées à quelque chose appelé rusage pour Linux et C. Y at-il quelque chose de similaire que je peux utiliser pour cela?


Edit: Ok, j'ai essayé le chemin de contre-performance, mais il a ajouté un certain nombre de données GC-chaque fois appelé, de sorte que le graphique pour l'utilisation de la mémoire et la collecte des ordures monté en flèche. Je suppose que je vais laisser cette partie pour l'instant.

Répondre

46

Vous pouvez également utiliser les propriétés System.Diagnostics.Process.TotalProcessorTime et System.Diagnostics.ProcessThread.TotalProcessorTime pour calculer l'utilisation de votre processeur tel que décrit par article.

+0

Cela a fonctionné beaucoup mieux et n'a pas ajouté autant de pression sur le GC, juste une légère augmentation. Merci! –

+0

@axk L'article ne semble pas être disponible, pouvez-vous compléter votre réponse en indiquant simplement comment récupérer uniquement la partie processeur en cours? – J4N

8

Jetez un oeil à System.Diagnostics.PerformanceCounter. Si vous lancez perfmon.exe, vous verrez la gamme de compteurs de performance à votre disposition (définissez l''objet de performance' sur 'Process'), dont l'un est '% Processor Time'.

+1

Cette réponse fonctionne le mieux pour moi. Je voudrais ajouter cependant que: 1. Vous devez vous assurer que vous obtenez seulement la prochaine valeur du compteur une fois par seconde ou moins souvent que cela ou les résultats sont éteints, et 2. Si vous regardez CPU stats, vous devez diviser cela par Environment.ProcessorCount sinon vous obtenez des pourcentages fous comme jusqu'à 800% sur une machine à 8 cœurs. –

3

Il est bon que vous vous connectez à des moniteurs comme smartinspect. Mais Windows lui-même rassemble les données pour chaque ressource dans ce cas votre programme (ou processus). WMI est la norme pour la surveillance des applications. Nous pouvons voir les données capturées par WMI. De nombreux outils de gestion des applications, de surveillance de la santé ou de surveillance des applications prennent en charge WMI dès la sortie de la boîte. Par conséquent, je ne vous recommande pas de consigner votre utilisation du processeur dans l'application dans un fichier journal.

Si vous pensez que la disponibilité et les performances sont critiques, optez pour des solutions telles que la solution Microsoft Operations Manager.

Pour avoir une idée sur WMI et pour obtenir la liste des processus, voir ci-dessous: - Win32_PerfFormattedData_PerfProc_Process pour obtenir le temps Cpu, le filtre est processID See this article - Vous pouvez obtenir le processID de la classe Win32_Process.

WMI Made Easy For C# par Kevin Matthew Goss

oConn.Username = "JohnDoe"; 
oConn.Password = "JohnsPass"; 

System.Management.ManagementScope oMs = new System.Management.ManagementScope("\\MachineX", oConn);  

//get Fixed disk stats 
System.Management.ObjectQuery oQuery = new System.Management.ObjectQuery("select FreeSpace,Size,Name from Win32_LogicalDisk where DriveType=3"); 

//Execute the query 
ManagementObjectSearcher oSearcher = new ManagementObjectSearcher(oMs,oQuery); 

//Get the results 
ManagementObjectCollection oReturnCollection = oSearcher.Get(); 

//loop through found drives and write out info 
foreach(ManagementObject oReturn in oReturnCollection) 
{ 
    // Disk name 
    Console.WriteLine("Name : " + oReturn["Name"].ToString()); 
    // Free Space in bytes 
    Console.WriteLine("FreeSpace: " + oReturn["FreeSpace"].ToString()); 
    // Size in bytes 
    Console.WriteLine("Size: " + oReturn["Size"].ToString()); 
} 

Vous pouvez suivre ainsi le processus de système à distance.

+2

Ceci est strictement un outil de débogage, et le code qui enregistre cela ne sera même pas compilé dans la version finale. Seule la journalisation au niveau de la méthode sera compilée pour cela, au cas où je devrais essayer de reproduire un crash bizarre sur une machine différente. Merci pour les informations détaillées cependant, j'ai pris note de cela –

-2

Cet article du projet de code décrit comment utiliser la minuterie haute performance:

http://www.codeproject.com/KB/cs/highperformancetimercshar.aspx

Vous pouvez l'utiliser en temps l'exécution de votre code.

Ici vous pouvez trouver un certain nombre d'open source C# profileurs:

http://csharp-source.net/open-source/profile

+0

Je n'avais pas besoin d'un minuteur, j'avais besoin d'un moyen de mesurer combien de CPU le programme utilisait sur une période de temps, ce n'est pas directement lié au temps pris, il pourrait y avoir des opérations d'E/S qui bloquent par exemple. –

Questions connexes