C# 如何计算 .NET 应用程序中的并发线程数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15381174/
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-10 16:35:33  来源:igfitidea点击:

How to count the amount of concurrent threads in .NET application?

c#multithreadingvisual-studiodebuggingtask-parallel-library

提问by Fulproof

Having read Parallel.ForEach keeps spawning new threadsI am still in doubt whether it is a correct method of counting the number of concurrent there threads?

阅读Parallel.ForEach 不断产生新线程我仍然怀疑这是否是计算并发线程数的正确方法?

What I see is that method counts the number of simultaneously entered but not completed iterations (loops) in Parallel.ForEach.
Is it synonym of the number of concurrent threads conveying correct number of simultaneously run threads?
I'm not a specialist but I can imagine that:

我看到的是,该方法计算Parallel.ForEach.
它是传达正确数量的同时运行线程的并发线程数的同义词吗?
我不是专家,但我可以想象:

  • the threads can be re-used while its activity swapped somewhere for continuing later.
  • theoretically the thread engaged for a loop activity is kept in thread pool after a loop completion but not re-used for another
  • Or what are the possibilities of distorting the purity of experiment (of threads counting)?
  • 线程可以在其活动交换到某处以供以后继续使用时重新使用。
  • 理论上,用于循环活动的线程在循环完成后保留在线程池中,但不会重新用于另一个
  • 或者扭曲实验(线程计数)纯度的可能性是什么?

Anyway, how to directly count the amount of running threads of .NET process, preferably in (C#) code?

无论如何,如何直接计算.NET进程的运行线程数量,最好在(C#)代码中?

Update:

更新:

So, if to follow the Jeppe Stig Nielsen's answerand use for count

因此,如果按照Jeppe Stig Nielsen 的回答并用于计数

directThreadsCount = Process.GetCurrentProcess().Threads.Count;

then output is, both in Release (threadsCount == 7) and Debug (threadsCount == 15) mode is very similar:

然后输出是,在 Release (threadsCount == 7) 和 Debug (threadsCount == 15) 模式下都非常相似:

[Job 0 complete. 2 threads remaining but directThreadsCount == 7
[Job 1 complete. 1 threads remaining but directThreadsCount == 7
[Job 2 complete. 2 threads remaining but directThreadsCount == 7
[Job 4 complete. 2 threads remaining but directThreadsCount == 7
[Job 5 complete. 2 threads remaining but directThreadsCount == 7
[Job 3 complete. 2 threads remaining but directThreadsCount == 7
[Job 6 complete. 2 threads remaining but directThreadsCount == 7
[Job 9 complete. 2 threads remaining but directThreadsCount == 7
[Job 7 complete. 1 threads remaining but directThreadsCount == 7
[Job 8 complete. 0 threads remaining but directThreadsCount == 7
FINISHED

That is, the number of threads are not ever decreasing telling that the cited above methodis incorrect while System.Diagnostics.ProcessThreadgives "Class name is not valid at this point"

也就是说,线程数永远不会减少,说明上述方法不正确,System.Diagnostics.ProcessThread给出"Class name is not valid at this point"

Are my conclusions correct and why cannot ProcessThreadbe used?

我的结论是否正确,为什么不能ProcessThread使用

The used code of C# console application:

C#控制台应用程序使用的代码:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace Edit4Posting
{
public class Node
{

  public Node Previous { get; private set; }
  public Node(Node previous)
  {
    Previous = previous;
    }
  }
  public class Edit4Posting
  {

    public static void Main(string[] args)
    {
      int concurrentThreads = 0;
      int directThreadsCount = 0;
      int diagThreadCount = 0;

      var jobs = Enumerable.Range(0, 10);
      Parallel.ForEach(jobs, delegate(int jobNr)
      {
        int threadsRemaining = Interlocked.Increment(ref concurrentThreads);

        int heavyness = jobNr % 9;

        //Give the processor and the garbage collector something to do...
        List<Node> nodes = new List<Node>();
        Node current = null;
        //for (int y = 0; y < 1024 * 1024 * heavyness; y++)
        for (int y = 0; y < 1024 * 24 * heavyness; y++)
        {
          current = new Node(current);
          nodes.Add(current);
        }
        //*******************************
        //uncommenting next line gives: "Class name is not valid at this point"
        //diagThreadCount=System.Diagnostics.ProcessThread
        directThreadsCount = Process.GetCurrentProcess().Threads.Count;
        //*******************************
        threadsRemaining = Interlocked.Decrement(ref concurrentThreads);
        Console.WriteLine(
           "[Job {0} complete. {1} threads remaining but directThreadsCount == {2}",
            jobNr, threadsRemaining, directThreadsCount);
      });
      Console.WriteLine("FINISHED");
      Console.ReadLine();
    }
  }
}

采纳答案by Jeppe Stig Nielsen

There are different kinds of threads, I think. The operating system's threads for the application you're running, can be counted with:

我认为有不同种类的线程。您正在运行的应用程序的操作系统线程数可以计算为:

int number = Process.GetCurrentProcess().Threads.Count;

It seems to count System.Diagnostics.ProcessThreadinstances. Maybe you need to count another kind of thread, like "managed threads", so I'm not sure my answer is what you seek.

它似乎计算System.Diagnostics.ProcessThread实例。也许你需要计算另一种线程,比如“托管线程”,所以我不确定我的答案是你想要的。

回答by Jon Skeet

I'm not a specialist but I can imagine that the threads can be re used while its activity swapped somewhere.

我不是专家,但我可以想象线程可以在其活动在某处交换时重新使用。

No - apart from some veryspecific cases (which you almost certainly don't need to worry about) threads aren't use reentrantly. The thread will be reused to run another iteration (or some other task) afterthe current iteration has completed, but it won't be asked to do something else whileyour code is running.

否 - 除了一些非常具体的情况(您几乎肯定不需要担心)之外,线程不会重入使用。在当前迭代完成,该线程将被重用以运行另一个迭代(或某个其他任务),但不会您的代码运行要求它执行其他操作。

So your current approach is reasonable, basically.

所以你目前的方法基本上是合理的。

Anyway, how to directly count the amount of running threads in .NET?

无论如何,如何直接统计.NET中正在运行的线程数量?

You can look in perfmon, which will graph it for you. (If the process is under your control, it's simplest to start the process but make it wait for input, then open up perfmon, add a counter from the "Process" options, select "Thread Count" as the counter to add, and restrict it to the process you're interested in from the dropdown. Hit OK, and then make your process start working.)

您可以查看 perfmon,它会为您绘制图表。(如果进程在你的控制之下,最简单的方法是启动进程但让它等待输入,然后打开 perfmon,从“进程”选项中添加一个计数器,选择“线程计数”作为要添加的计数器,并限制从下拉列表中将其添加到您感兴趣的流程。点击“确定”,然后让您的流程开始工作。)

EDIT: To answer the update:

编辑:要回答更新:

That is, the number of threads are not ever decreasing telling that the cited above method is incorrect

也就是说,线程的数量不会减少,说明上面引用的方法是不正确的

No, all it shows is that the number of threads actively running your code decreases, but the threads are kept around. That's entirely natural for a thread pool.

不,它所显示的是主动运行代码的线程数量减少了,但线程保持不变。这对于线程池来说是很自然的。

why cannot ProcessThreadbe used?

为什么不能ProcessThread使用?

You're simply using it inappropriately. Jeppe said that the system was counting the instances of ProcessThreadwhereas your code tries to assign a class to a variable:

你只是不恰当地使用它。Jeppe 说系统正在计算 的实例,ProcessThread而您的代码试图将一个类分配给一个变量:

diagThreadCount=System.Diagnostics.ProcessThread

That's simply invalid code. The error message shows that the compiler realizes it's the name of a type, but you can't just assign a type name to a variable.

那只是无效的代码。错误消息表明编译器意识到它是类型的名称,但您不能仅将类型名称分配给变量。