14

我有一个 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类,因此我无法在那里实现线程池。

实现这一点的最佳方法是什么?

谢谢,保罗

4

3 回答 3

21

你想要Semaphore 类。简而言之,它是一个在任何时候只允许指定数量的调用者通过的锁。

由于您不控制线程的创建,因此您确实需要小心死锁情况。信号量不是可重入感知的——如果给定线程多次进入一个信号量,它将占用多个槽。因此,如果您的调用者的每个线程都多次进入您的信号量,则可能会出现死锁。

于 2012-04-16T15:18:57.647 回答
9

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

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();
  }
}
于 2012-04-16T15:31:30.227 回答
3

通常为此使用信号量。将其初始化为 10 个单位。在 DoUsefulThings() 之前 wait() 一个单元,之后一个单元 signal()。

于 2012-04-16T15:19:51.553 回答