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

57,169

Solution 1

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.ProcessThread instances. Maybe you need to count another kind of thread, like "managed threads", so I'm not sure my answer is what you seek.

Solution 2

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 very specific 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) after the current iteration has completed, but it won't be asked to do something else while your code is running.

So your current approach is reasonable, basically.

Anyway, how to directly count the amount of running threads in .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.)

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 ProcessThread be used?

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

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.

Share:
57,169

Related videos on Youtube

Fulproof
Author by

Fulproof

Updated on March 15, 2020

Comments

  • Fulproof
    Fulproof about 4 years

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

    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:

    • 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?

    Update:

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

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

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

    [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 method is incorrect while System.Diagnostics.ProcessThread gives "Class name is not valid at this point"

    Are my conclusions correct and why cannot ProcessThread be used?

    The used code of C# console application:

    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();
        }
      }
    }
    
  • svick
    svick about 11 years
    In theory, Threads and ProcessThreads could be different. In practice, they are almost always the same.
  • Jeppe Stig Nielsen
    Jeppe Stig Nielsen about 11 years
    @svick A very simple console application that writes out the above property, gives 4, sometimes 3. I would think it was a one-threaded application. When the same application is debugged (debugger attached), the number is much higher, like 12 or 13. In another application, if I start a lot of new threads with the System.Threading.Thread class, the count of System.Diagnostics.ProcessThread increases by approximately the correct number. (Tried on Windows 7 64-bit.)
  • Fulproof
    Fulproof about 11 years
    diagThreadCount=System.Diagnostics.ProcessThread is not complete code, I could not finish it since Intellisense and compiler gives an error and refuses to use ProcessThread
  • Jon Skeet
    Jon Skeet about 11 years
    @Fulproof: The compiler does find the ProcessThread class, otherwise it wouldn't have given you an error of "Class name is not valid at this point". But there are no static members of ProcessThread, therefore nothing for Intellisense to suggest. It's not clear what you were trying to achieve with ProcessThread anyway.
  • Fulproof
    Fulproof about 11 years
    to see what is the mentioned "the count of System.Diagnostics.ProcessThread", what is the difference.. How to use it?
  • Jon Skeet
    Jon Skeet about 11 years
    @Fulproof: What is the difference between that and what? Jeppe's answer seemed pretty clear to me - Process.GetCurrentProcess().Threads returns you a collection of ProcessThread references.
  • Fulproof
    Fulproof about 11 years
    Jeppe's comment to his answer tells about "the count of System.Diagnostics.ProcessThread increases by approximately the correct number" in response to @svick's comment "Threads and ProcessThreads could be different. In practice, they are almost always the same" I just wanted to understand the difference and well, see, it