user1158555
user1158555

Reputation: 177

How many Threads in my method?

I'm been searching the web for this answer and cannot find anything that really makes since to me.

I have a program that I am running and I want to count how many threads are in my method at a given time.

I have code in my Main() function:

Parallel.Invoke(MyMethod,MyMethod,MyMethod,MyMethod);


private static void MyMethod()
{
    //how many threads are waiting here???  <--- this is what I am after
    lock (myObj)
    {
        //one thread at a time please
    }
}

Can anyone shed light here??

Upvotes: 7

Views: 292

Answers (3)

JaredPar
JaredPar

Reputation: 755557

There is no way to directly query how many threads are in a given function. The only way is to do manual tracking

private static int s_threadCount;

private static void MyMethod() {
  Interlocked.Increment(ref s_threadCount);
  try {
    ...
  } finally {
    Interlocked.Decrement(ref s_threadCount);
  }
}

Note: If this method can be recursively entered this won't accurately count the number of threads but instead will count number of threads + number of times they recursively entered the function.

Upvotes: 12

Jon Hanna
Jon Hanna

Reputation: 113392

Not expecting many simultaneous enter/leaves and don't care about re-entrancy:

static int _cThreads;
static void SomeMethod()
{
  Interlocked.Increment(ref _cThreads);
  try
  {
    /* blah */
  }
  finally
  {
    Interlocked.Decrement(ref _cThreads);
  }
}

Do care about re-entrancy:

static IDictionary<int, int> _cThreads; // ConcurrentDictionary or alternative thread-safe dictionary
static void SomeMethod()
{
  if(_cThreads.ContainsKey(Thread.CurrentThread.ManagedThreadId))//note that only this thread will hit this key
    _cThreads[Thread.CurrentThread.ManagedThreadId]++
  else
    _cThreads[Thread.CurrentThread.ManagedThreadId] = 1;
  try
  {
    /* blah */
   //When I care about the count then it's _cThreads.Values.Where(v => v != 0).Count()
   //which will mutate while we're trying to count it, but then any
   //answer to this is going to have a degree of staleness
   /*blah*/
  }
  finally
  {
    _cThreads[Thread.CurrentThread.ManagedThreadId]--;
  }
}

If you don't care about re-entrancy, but are expecting lots of simultaneous, but won't want to check the total every time, then use a striped counter. This will be appreciably slower with low contention, but much faster with high contention between cores, and may be applicable to your case.

Upvotes: 1

Marc Gravell
Marc Gravell

Reputation: 1064204

The only way to do that would be to add a counter:

static int counter;
... 
static void SomeMethod() {
    int threadsInMethod = Interlocked.Increment(ref counter);
    try {
        code here
    } finally {
        Interlocked.Decrement(ref counter);
    }
}

Caveat: if the method is re-entrant it will overcount itself while nested.

Upvotes: 3

Related Questions