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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/934497/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 03:39:20  来源:igfitidea点击:

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

c#performancemultithreadingmemory-managementcpu-usage

提问by Timothy Khouri

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's fine too.

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

Example of what I need:

我需要的示例:

Thread myThread = Thread.CurrentThread;

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

Console.WriteLine(GetThreadSpecificCpuUsage(myThread));

采纳答案by Tetraneutron

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

这是一个可以满足您要求的示例 http://www.codeproject.com/KB/system/processescpuusage.aspx

回答by erikkallen

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?

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

回答by jerryjvl

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

如前所述,无法回答内存使用情况,因为这是整个进程的一个属性,但 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
}

回答by Lee Jensen

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.

这是一个简单的程序,它启动 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();
        }
    }
}
}

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.

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