2012-04-16 36 views
14

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

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

回答

21

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

由于您不控制线程的创建,因此您需要小心有关死锁的情况。信号量不会重入意识 - 如果给定的线程不止一次地进入信号量,它将占用多个时隙。所以如果你的每个调用者的线程不止一次地进入你的信号量,就有可能发生死锁。

3

为此,习惯使用信号量。初始化为10个单位。在DoUsefulThings()之前等待()一个单位,然后在一个单位之后信号()。

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(); 
    } 
} 
+1

+1注意你应该在try/catch的'finally'块中退出信号量。这是重要的东西 - 万一你的代码抛出一个异常,你想确保信号退出。 – 2012-04-16 15:36:04

相关问题