2013-04-19 4 views
5

मुझे समग्र सिस्टम के साथ-साथ एक विशिष्ट प्रक्रिया के लिए सीपीयू और रैम उपयोग की गणना करने की आवश्यकता है। मैंने इसे सी # में कभी नहीं किया है। तो मैं निम्नलिखित कोड के साथ आने में सक्षम था (है कि मैं इस वेब साइट पर नमूनों से मुख्य रूप से लिया):सी # प्रदर्शन काउंटर डेटा "मानचित्र पर सभी"

try 
{ 
    Process proc = Process.GetCurrentProcess(); 
    string strProcName = proc.ProcessName; 
    Console.WriteLine("Process: " + strProcName); 

    using (PerformanceCounter total_cpu = new PerformanceCounter("Process", "% Processor Time", "_Total", true)) 
    { 
     using (PerformanceCounter process_cpu = new PerformanceCounter("Process", "% Processor Time", strProcName, true)) 
     { 
      for (; ;) 
      { 
       Console.CursorTop = 1; 
       Console.CursorLeft = 0; 

       float t = total_cpu.NextValue()/Environment.ProcessorCount; 
       float p = process_cpu.NextValue()/Environment.ProcessorCount; 
       Console.WriteLine(String.Format("Total CPU (%) = {0}\t\t\nApp CPU (%) = {1}\t\t\nApp RAM (KB) = {2}", 
        t, p, Process.GetCurrentProcess().WorkingSet64/(1024) 
        )); 

       System.Threading.Thread.Sleep(100); 
      } 
     } 
    } 
} 
catch(Exception ex) 
{ 
    Console.WriteLine("Exception: " + ex); 
} 

लेकिन क्या यह मुझे देता है डेटा "सभी नक्शे पर"। एक नज़र डालें:

  1. यह प्रदर्शन काउंटर चल की तरह लगता है द्वारा एक बहुत महंगा ऑपरेशन है:

    enter image description here

    enter image description here

    enter image description here

    तो किसी को इन बातों का जवाब दे सकते स्वयं - यह लगभग 5% तक CPU उपयोग बढ़ाता है। मैंने सी ++ के साथ सीपीयू काउंटर का एक टन किया और वे चलाने के लिए बहुत अधिक CPU समय नहीं लेते।

  2. इसके अलावा मैंने जो कहा है उसके अलावा, पहली बार लूप ऊपर 2 सेकंड देरी के साथ चलता है! यह सचमुच 2 सेकंड के लिए लटकता है। क्या यह सामान्य है? अगर ऐसा है, मैं विश्वास नहीं कर सकता कि वे इसे एक प्रदर्शन काउंटर :) कॉल करने के लिए एक दुस्साहस था

  3. हालांकि मेरी रैम पढ़ने सुंदर एक कार्य प्रबंधक द्वारा रिपोर्ट के करीब है, सीपीयू उत्पादन पूरी तरह से है बंद। क्या कोई मुझे बता सकता है कि मैं यहाँ क्या गलत कर रहा हूं? आदि % Processor Time, _Total,:

  4. इसके अलावा, मैं PerformanceCounter class के लिए किसी भी प्रलेखन, कि इन सब की व्याख्या कर सकते हैं नहीं कर पा रहे? और सबसे महत्वपूर्ण बात यह है कि वे केवल अंग्रेजी हैं? क्या उन्हें स्थानीयकृत किया जाना चाहिए?

  5. प्रक्रिया इसके नाम से निर्दिष्ट है। लेकिन अगर मेरे पास एक ही नाम के तहत एक से अधिक प्रक्रियाएं चल रही हैं तो क्या होगा। फिर क्या?

उत्तर

0

यहाँ मैं के साथ आया है, लेकिन वह अप्रबंधित API का उपयोग करके किया जाता है:

[DllImport("kernel32.dll")] 
[return: MarshalAs(UnmanagedType.Bool)] 
static extern bool GetProcessTimes(IntPtr hProcess, out System.Runtime.InteropServices.ComTypes.FILETIME 
    lpCreationTime, out System.Runtime.InteropServices.ComTypes.FILETIME lpExitTime, out System.Runtime.InteropServices.ComTypes.FILETIME lpKernelTime, 
    out System.Runtime.InteropServices.ComTypes.FILETIME lpUserTime); 

[DllImport("kernel32.dll")] 
[return: MarshalAs(UnmanagedType.U4)] 
static extern UInt32 GetTickCount(); 

static bool gbSetOldData = false; 
static UInt32 gmsOldTickCount = 0; 
static ulong gnsOldKernelTime = 0; 
static ulong gnsOldUserTime = 0; 

public static double getCPUUsageForProcess(int nProcID = 0) 
{ 
    //Get CPU usage for the process in with ID in 'nProcID' 
    //'nProcID' = process ID, or 0 for the current process 
    //RETURN: 
    //  = CPU usage: [0.0 - 1.0] 
    //  = Negative if error 
    double fCPUUsage = -1.0; 
    try 
    { 
     IntPtr hProcess = nProcID != 0 ? Process.GetProcessById(nProcID).Handle : Process.GetCurrentProcess().Handle; 

     System.Runtime.InteropServices.ComTypes.FILETIME ftCreated, ftExit, ftKernel, ftUser; 
     if (GetProcessTimes(hProcess, out ftCreated, out ftExit, out ftKernel, out ftUser)) 
     { 
      UInt32 dwmsNewTickCount = GetTickCount(); 

      ulong nsNewKernelTime = (ulong)ftKernel.dwHighDateTime; 
      nsNewKernelTime <<= 32; 
      nsNewKernelTime |= (ulong)(uint)ftKernel.dwLowDateTime; 

      ulong nsNewUserTime = (ulong)ftUser.dwHighDateTime; 
      nsNewUserTime <<= 32; 
      nsNewUserTime |= (ulong)(uint)ftUser.dwLowDateTime; 

      if (gbSetOldData) 
      { 
       //Adjust from 100-nanosecond intervals to milliseconds 
       //100-nanosecond intervals = 100 * 10^-9 = 10^-7 
       //1ms = 10^-3 
       fCPUUsage = (double)((nsNewKernelTime - gnsOldKernelTime) + (nsNewUserTime - gnsOldUserTime))/
        (double)((dwmsNewTickCount - gmsOldTickCount) * 10000); 

       //Account for multiprocessor architecture 
       fCPUUsage /= Environment.ProcessorCount; 

       //In case timer API report is inaccurate 
       if (fCPUUsage > 1.0) 
        fCPUUsage = 1.0; 
      } 
      else 
      { 
       //For the first run, assume no CPU usage 
       fCPUUsage = 0.0; 
      } 

      //Remember data 
      gnsOldKernelTime = nsNewKernelTime; 
      gnsOldUserTime = nsNewUserTime; 
      gmsOldTickCount = dwmsNewTickCount; 
      gbSetOldData = true; 
     } 
    } 
    catch 
    { 
     //Failed 
     fCPUUsage = -1.0; 
    } 

    return fCPUUsage; 
} 

और यह कि कैसे आप इसे कहते होता है:

int nDummy = 1; 

for (; ;) 
{ 
    double fCPU = getCPUUsageForProcess(); 

    Console.CursorTop = 1; 
    Console.CursorLeft = 0; 

    int nCpu = (int)(fCPU * 100); 
    Console.WriteLine("CPU%: {0}\t\t", nCpu); 

    //Time filler 
    long j = 0; 
    for (; j < 1000000; j++) 
    { 
     nDummy += (int)Math.Cos(1/(j + 1)); 
    } 

    //Don't hog all CPU time! 
    System.Threading.Thread.Sleep(500); 
} 

मैं सुनिश्चित नहीं हूं अगर .NET की एक समान विधि है। यदि कोई है (जिसमें ऊपर दी गई सभी सीमाएं नहीं हैं) तो मैं इसे सुनना चाहूंगा?

0

आपका कोड ठीक लगता है लेकिन कुल सीपीयू उपयोग काउंटर गलत है। आप प्रोसेसर की बजाय प्रक्रिया है। इसके अलावा प्रतिशत को विभाजित न करें क्योंकि विंडोज हमेशा सीपीयू का उपयोग करता है जिसमें कम लोड होता है जब तक कि आपका ऐप बहु थ्रेडिंग के लिए नहीं बनाया जाता है। दूसरी बात, आपका नमूना है, यह बहुत तेज़ है। मैंने इसे 1 सेकंड तक धीमा कर दिया। आप काउंटर

try 
{ 
    Process proc = Process.GetCurrentProcess(); 
    string strProcName = proc.ProcessName; 
    Console.WriteLine("Process: " + strProcName); 

    using (PerformanceCounter total_cpu = new PerformanceCounter("Processor", "% Processor Time", "_Total", true)) 
    { 
     using (PerformanceCounter process_cpu = new PerformanceCounter("Process", "% Processor Time", strProcName, true)) 
     { 
      for (; ;) 
      { 
       Console.CursorTop = 1; 
       Console.CursorLeft = 0; 

       float t = total_cpu.NextValue() ; 
       float p = process_cpu.NextValue(); 
       Console.WriteLine(String.Format("Total CPU (%) = {0}\t\t\nApp CPU (%) = {1}\t\t\nApp RAM (KB) = {2}", 
        t, p, Process.GetCurrentProcess().WorkingSet64/(1024) 
        )); 

       System.Threading.Thread.Sleep(1000); 
      } 
     } 
    } 
} 
catch(Exception ex) 
{ 
    Console.WriteLine("Exception: " + ex); 
} 
से एक बेहतर प्रतिक्रिया होनी चाहिए
संबंधित मुद्दे