How can I get CPU usage and/or RAM usage of a *THREAD* in C# (managed code)?

前端 未结 4 798
盖世英雄少女心
盖世英雄少女心 2020-12-09 19:00

I know how to get CPU usage and memory usage for a process, but I was wondering how to get it on a per-thread level. If the best solution is to do some P-Invoking, then that

相关标签:
4条回答
  • 2020-12-09 19:11

    You can't get memory usage per thread because memory is shared between all threads in a process. How would the OS know whether you allocated memory in one thread and used it in another. And what would it mean?

    0 讨论(0)
  • 2020-12-09 19:16

    Here is a simple program that launches 5 threads that consume different amounts of CPU and then matches up what managed thread is consuming what amount of CPU.

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    using System.Threading;
    
    class Program
    {
    [DllImport("Kernel32", EntryPoint = "GetCurrentThreadId", ExactSpelling = true)]
    public static extern Int32 GetCurrentWin32ThreadId();
    
    static void Main(string[] args)
    {
        Dictionary<int, Thread> threads = new Dictionary<int, Thread>();
    
        // Launch the threads
        for (int i = 0; i < 5; i++)
        {
            Thread cpuThread = new Thread((start) =>
            {
                lock (threads)
                {
                    threads.Add(GetCurrentWin32ThreadId(), Thread.CurrentThread);
                }
    
                ConsumeCPU(20 * (int)start);
            });
            cpuThread.Name = "T" + i;
            cpuThread.Start(i);
        }
    
        // Every second wake up and see how much CPU each thread is using.
        Thread monitoringThread = new Thread(() =>
            {
                Stopwatch watch = new Stopwatch();
                watch.Start();
    
                while (true)
                {
                    Thread.Sleep(1000);
                    Console.Write("\r");
    
                    double totalTime = ((double)watch.ElapsedMilliseconds);
                    if (totalTime > 0)
                    {
                        Process p = Process.GetCurrentProcess();
                        foreach (ProcessThread pt in p.Threads)
                        {
                            Thread managedThread;
                            if (threads.TryGetValue(pt.Id, out managedThread))
                            {
                                double percent = (pt.TotalProcessorTime.TotalMilliseconds / totalTime);
                                Console.Write("{0}-{1:0.00} ", managedThread.Name, percent);
                            }
                        }
                    }
                }
            });
        monitoringThread.Start();
    }
    
    
    // Helper function that generates a percentage of CPU usage
    public static void ConsumeCPU(int percentage)
    {
        Stopwatch watch = new Stopwatch();
        watch.Start();
        while (true)
        {
            if (watch.ElapsedMilliseconds > percentage)
            {
                Thread.Sleep(100 - percentage);
                watch.Reset();
                watch.Start();
            }
        }
    }
    }
    

    Note that it is possible that the CLR will change the native thread that the managed thread is executing under. However, in practice I am not sure how often this actually happens.

    0 讨论(0)
  • 2020-12-09 19:20

    As said, memory use cannot be answered since that is an attribute of the process as a whole, but CPU use:

    Process p = Process.GetCurrentProcess(); // getting current running process of the app
    foreach (ProcessThread pt in p.Threads)
    {
        // use pt.Id / pt.TotalProcessorTime / pt.UserProcessorTime / pt.PrivilegedProcessorTime
    }
    
    0 讨论(0)
  • 2020-12-09 19:22

    Here's an example which does what you want http://www.codeproject.com/KB/system/processescpuusage.aspx

    0 讨论(0)
提交回复
热议问题