一个只允许N个并发线程的函数

时间:2012-04-16 15:17:22

标签: c# multithreading .net-3.5

我有一个Visual Studio 2008 C#.NET 3.5项目,其中一个类侦听来自另一个多线程类的事件调用。我需要确保我的事件只允许同时访问最多10个线程。第11个线程应该阻塞,直到10个完成中的一个。

myobj.SomeEvent += OnSomeEvent;

private void OnSomeEvent(object sender, MyEventArgs args)
{
    // allow up to 10 threads simultaneous access. Block the 11th thread.
    using (SomeThreadLock lock = new SomeThreadLock(10))
    {         
        DoUsefulThings(args.foo);
    }
}

我无法控制其他MyObj类,所以我无法在那里实现线程池。

实施此方法的最佳方法是什么?

谢谢, PaulH

3 个答案:

答案 0 :(得分:21)

你想要Semaphore class。简而言之,它是一个锁,只允许指定数量的呼叫者随时通过。

由于您不控制线程的创建,因此您需要注意死锁情况。信号量不是可重入的 - 如果给定的线程不止一次地进入信号量,它将需要不止一个时隙。因此,如果您的每个调用者的线程不止一次进入您的信号量,就有可能出现死锁。

答案 1 :(得分:9)

为此使用Semaphore。构造函数参数对刚引入类的人来说有点混乱。第一个参数指定通过立即允许的初始线程数。第二个参数指定在任何给定时间允许的最大线程数。

myobj.SomeEvent += OnSomeEvent;
Semaphore semaphore = new Semaphore(10, 10);

private void OnSomeEvent(object sender, MyEventArgs args)
{
  semaphore.WaitOne();
  try
  {
    DoUsefulThings(args.foo);
  }
  finally
  {
    semaphore.Release();
  }
}

答案 2 :(得分:3)

习惯上使用信号量。将其初始化为10个单位。在DoUsefulThings()之前的一个单位的wait(),之后的一个单位的信号()。