Функция, которая разрешает только N параллельных потоков

У меня есть проект Visual Studio 2008 С#.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, поэтому я не могу реализовать threadpool там.

Каков наилучший способ реализовать это?

Спасибо, PaulH

Ответы

Ответ 1

Вы хотите класс семафора. Короче говоря, это блокировка, которая позволяет в любое время разрешить определенное количество абонентов.

Поскольку вы не контролируете создание потоков, вам нужно быть осторожным в ситуациях взаимоблокировки. Семафоры не поддерживают повторный вход - если данный поток входит в семафор более одного раза, он занимает более одного слота. Поэтому, если каждый из ваших потоков вызывающего пользователя входит в ваш семафор более одного раза, существует возможность блокировки.

Ответ 2

Используйте для этого 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();
  }
}

Ответ 3

Обычно для этого используется семафор. Инициализируйте его до 10 единиц. wait() для одного устройства до DoUsefulThings(), сигнала() на один блок после.