1

Possible Duplicate:
Limiting the number of threads executing a method at a single time

In a single app we need to limit executing a section of code to 4 threads. This section is not the start/end of the thread, it is a section of code inside the thread.

How to do this with one is easy - create an EventWaitHandle and wait/signal on it. But every way I've thought of to do 4 leaves the possibility of determining I need to wait, another thread exists the section and signals, and I then wait - forever.

So what is the most light-weight way to do this when all threads are in a single app?

Background: We are changing our licensing model to allow a maximum of N (4 in this example) threads calling our library consecutively. Because we're a library, not a server, we don't control the thread usage (like databases can). In the case of a web app, the calling app also doesn't control the number of threads and so we need to pause thread 5 calling us until one the first 4 exit that code.

Community
  • 1
  • 1
David Thielen
  • 28,723
  • 34
  • 119
  • 193
  • What do you want to happen when the number of maximum licenses is already in use? Fail or wait for license? – larsmoa Nov 04 '12 at 00:37

2 Answers2

3

Semaphore is the threading primitive that would fit you perfectly. It will allow up to the specified number of concurrent users; an additional user will block.

private static Semaphore _semaphore = new Semaphore(4, 4);

Then for the code you want to share:

_semaphore.WaitOne();
try
{
    // protected code goes here
}
finally
{
    _semaphore.Release();
}

The nice thing about this in terms of overhead is that WaitOne is efficient: it blocks your thread properly, and you get unblocked efficiently when someone calls a Release.

Roman Starkov
  • 59,298
  • 38
  • 251
  • 324
  • 2
    I deleted my answer after reading yours, I think `Semaphore` fits the bill perfectly. – ta.speot.is Nov 04 '12 at 00:35
  • @romkyns - thank you. I've stayed aware from Semaphores for the last couple of years because they're slower. And so I forgot to take a look there. – David Thielen Nov 04 '12 at 00:39
  • @DavidThielen I suppose if you want this to work across several processes (and you do, since otherwise your licensing restriction is easy to work around) then you should use the constructor that adds a name, for an OS-wide semaphore. That's going to be slower, unfortunately, but hopefully not unaffordable. – Roman Starkov Nov 04 '12 at 00:59
0

I would use Semaphore, as mentioned by romkyns. However, the operations under semaphore should be quite big - the overhead is substantial. Consider if SemaphoreSlim is a good fit for your case (i.e. if the licensing is for a single process only, see How do I choose between Semaphore and SemaphoreSlim? and MSDN).

Off-topic comments:

This seems like a very inconvinient licensing scheme. What do you want to achieve doing this? The licensing scheme should reflect buisness value and talking about number of concurrent threads seems hard to communicate to management. Secondly, how will this licensing scheme help you communicate the need for more licenses? It seems hard to monitor the usage if you base the licenses on the number of threads, making it hard to justify the need for more licenses to your users.

Community
  • 1
  • 1
larsmoa
  • 12,604
  • 8
  • 62
  • 85
  • I am open to better approaches for licensing. In the past we priced based on the number of cores on the computer. But systems nowadays have a large number of cores, yet in many cases most of that processing power is not for calling our system. – David Thielen Nov 04 '12 at 00:41
  • @DavidThielen: it's hard to make any suggestions without knowing what to license, but I would certainly consider if it's possible to license by modules/functionality instead. – larsmoa Nov 04 '12 at 00:55
  • We're a reporting system. Pricing is basically a way of allocating our costs across all of our customers. And the key measure there is number of reports run. If you run 10/month and one of our banking customers runs 80K/day, that is the fundamental action we need to price against. Number of threads is a very simple limit that maps well to usage. – David Thielen Nov 04 '12 at 01:48