如何在 C#(托管代码)中获取 *THREAD* 的 CPU 使用率和/或 RAM 使用率?

Posted

技术标签:

【中文标题】如何在 C#(托管代码)中获取 *THREAD* 的 CPU 使用率和/或 RAM 使用率?【英文标题】:How can I get CPU usage and/or RAM usage of a *THREAD* in C# (managed code)? 【发布时间】:2010-10-30 09:19:03 【问题描述】:

我知道如何获取进程的 CPU 使用率和内存使用率,但我想知道如何在每个线程级别获取它。如果最好的解决方案是做一些 P-Invoking,那也没关系。

我需要的示例:

Thread myThread = Thread.CurrentThread;

// some time later in some other function...

Console.WriteLine(GetThreadSpecificCpuUsage(myThread));

【问题讨论】:

【参考方案1】:

这是一个简单的程序,它启动 5 个消耗不同 CPU 量的线程,然后匹配哪个托管线程消耗多少 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();
        
    


请注意,CLR 可能会更改托管线程在其下执行的本机线程。但是,在实践中,我不确定这种情况实际发生的频率。

【讨论】:

【参考方案2】:

如前所述,内存使用无法回答,因为这是整个进程的属性,但 CPU 使用:

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

【讨论】:

请注意,ProcessThread 不直接连接到 .NET 线程。另见:***.com/a/24085127/6841224 或 social.msdn.microsoft.com/Forums/en-US/…【参考方案3】:

您无法获取每个线程的内存使用情况,因为内存在进程中的所有线程之间共享。操作系统如何知道您是否在一个线程中分配内存并在另一个线程中使用它。这意味着什么?

【讨论】:

但通常 TLS 仅用于保存对共享内存中对象的引用。 确定线程使用情况的不是操作系统,而是框架本身。 @JuanCarlosDiaz 操作系统或框架无关紧要,同样的问题仍然适用。【参考方案4】:

这是一个执行您想要的示例的示例 http://www.codeproject.com/KB/system/processescpuusage.aspx

【讨论】:

以上是关于如何在 C#(托管代码)中获取 *THREAD* 的 CPU 使用率和/或 RAM 使用率?的主要内容,如果未能解决你的问题,请参考以下文章

如何从非托管 C++ 代码获取结构化列表值到 C#?

如何在托管代码(C#)中从本机代码(C++)获取字符串数组

从 C# 线程内的非托管 dll 运行函数

如何在从 C 到 C# 的结构中获取非托管可变长度 C 数组?

C# 如何获取当前方法所在的线程?

通过 Marshal.GetFunctionPointerForDelegate 从本机 (C++) 线程调用托管函数 (C#)