2013-06-05 2 views
0

Il suffit d'entrer dans la programmation C# alors s'il vous plaît nu avec moi :)C# Réduire l'utilisation du processeur - Bande passante du réseau Script

Je vous écris cette classe pour surveiller la bande passante en passant par toutes les interfaces réseau. Bien que tout cela fonctionne à merveille, je veux essayer de réduire l'utilisation du processeur lors de la requête. La raison en est que je lance cette opération toutes les deux secondes, ce qui ajoute environ 7 à 8% d'utilisation du processeur au processus à chaque fois. Y a-t-il un moyen de réduire la quantité de cycles CPU?

PerformanceCounterCategory category = new PerformanceCounterCategory("Network Interface"); 
     String[] instancename = category.GetInstanceNames(); 

     foreach (string name in instancename) 
     { 
      String networkCard = name; 

      const int numberOfIterations = 10; 

      PerformanceCounter bandwidthCounter = new PerformanceCounter("Network Interface", "Current Bandwidth", networkCard); 

      float bandwidth = bandwidthCounter.NextValue(); 

      PerformanceCounter dataSentCounter = new PerformanceCounter("Network Interface", "Bytes Sent/sec", networkCard); 

      PerformanceCounter dataReceivedCounter = new PerformanceCounter("Network Interface", "Bytes Received/sec", networkCard); 

      float sendSum = 0; 
      float receiveSum = 0; 

      for (int index = 0; index < numberOfIterations; index++) 
      { 
       sendSum += dataSentCounter.NextValue(); 
       receiveSum += dataReceivedCounter.NextValue(); 
      } 
      float dataSent = sendSum; 
      float dataReceived = receiveSum; 


      double dout = (((8 * (dataSent))/(bandwidth * numberOfIterations) * 100) * 1024)/100; 
      double din = (((8 * (dataReceived))/(bandwidth * numberOfIterations) * 100) * 1024)/100; 

      dout = Math.Round(dout, 2); 
      din = Math.Round(din, 2); 

      string doutround = Convert.ToString(dout); 
      string dinround = Convert.ToString(din); 



      String output = dinround + "/" + doutround; 


       GlobalsWMI.NetIOs.Add(output); 



     } 
     String tooutput = String.Join("AND", GlobalsWMI.NetIOs); 
     GlobalsWMI.NetIOs.Clear(); 
     return tooutput; 

Merci,

+0

Comment ça marche? Commencer un nouveau processus est relativement cher donc si vous pouvez le démarrer une fois et l'exécuter périodiquement cela réduirait * probablement * le pic. En outre, de quel genre de chiffres parlez-vous avec instanceNames et numberOfIterations? – LoztInSpace

+0

J'ai couru le profileur et peux voir un certain nombre de choses: d'abord PerformanceCounter.NextValue() sur ma machine utilise jusqu'à 6-10% de CPU Je ne sais pas pourquoi mais juste fait. J'ai également remarqué que la création des noms d'instance est lente (category.GetInstanceNames()). Je me demande s'il y a une façon différente de le faire. – TheKingDave

+0

Avez-vous regardé ma réponse (je suis désespéré pour rep). – TheKingDave

Répondre

0

Ok j'ai essayé différentes choses et je pense que cette version est beaucoup plus rapide:

private string GetNetworkUsage(System.Net.NetworkInformation.NetworkInterface[] nis) 
{ 

foreach (NetworkInterface ni in nis) 
      { 
       float bandwidth = ni.Speed; 
       const int numberOfIterations = 10; 

       float sendSum = 0; 
       float receiveSum = 0; 

       float lastRec = ni.GetIPv4Statistics().BytesReceived; 
       float lastSent = ni.GetIPv4Statistics().BytesSent; 

       for (int index = 0; index < numberOfIterations; index++) 
       { 
        System.Threading.Thread.Sleep(10); 
        float br = ni.GetIPv4Statistics().BytesReceived; 
        float bs = ni.GetIPv4Statistics().BytesSent; 
        receiveSum += br - lastRec; 
        sendSum += bs - lastSent; 

        lastRec = br; 
        lastSent = bs; 

       } 

       float dataSent = sendSum; 
       float dataReceived = receiveSum; 

       double dout = (((8 * (dataSent))/(bandwidth) * 100) * 1024)/100; 
       double din = (((8 * (dataReceived))/(bandwidth) * 100) * 1024)/100; 

       dout = Math.Round(dout, 2); 
       din = Math.Round(din, 2); 

       string doutround = Convert.ToString(dout); 
       string dinround = Convert.ToString(din); 

       String output = dinround + "/" + doutround; 


       GlobalsWMI.NetIOs.Add(output); 
      } 

      String tooutput = String.Join("AND", GlobalsWMI.NetIOs); 
      GlobalsWMI.NetIOs.Clear(); 
      return tooutput; 
} 

appel comme ceci:

System.Net.NetworkInformation.NetworkInterface[] nis = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces(); 

    // this is you for loop add you sleep or however you do it here 
    for (int i = 0; i < int.MaxValue; i++) 
    { 
     Console.WriteLine(test(nis)); 
    } 

Essayé sur mon système et il utilise moins de CPU et plus vite mais je vérifierais que les chiffres sont conformes à vos attentes.

0

Vous pouvez réduire l'utilisation du processeur sur le temps avec un System.Threading.Thread.Sleep (x) à certains endroits - Votre chèque durerait plus longtemps, mais avec moins d'utilisation CPU moyenne.

+0

Non ce ne serait pas. Il utiliserait le même CPU mais sur une période différente. – LoztInSpace

+0

Correct, donc l'utilisation moyenne du CPU est réduite ;-) –

+0

D'accord, mais ce n'était pas la question. – LoztInSpace

Questions connexes