Reputation: 177
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
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
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
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