Семафор действительно случайный здесь; это просто ограничивает количество потребителей, которые могут приобретать ресурсы одновременно. Синхронизация на самом деле происходит из оператора lock
(критический раздел).
Насколько я могу судить, этот код является поточно-ориентированным. Когда вы говорите, что «выдает один и тот же объект» - возможно, я неправильно понимаю вопрос, но должен выдавать тот же объект, потому что когда вызывающие вызывают метод Release
, они возвращают тот же ресурс, который они получили изначально, поэтому один и тот же объект будет находиться в очереди в нескольких точках во время выполнения.
Если вы имеете в виду, что метод RequestResource
возвращает ресурсы, которые уже были получены, но не освобождены, есть только три возможные причины, по которым я могу подумать:
В очереди содержались повторяющиеся ресурсы с начала;
Потребитель дважды вызывал метод Release
. В вашем методе Release
вы фактически не проверяете, находится ли ресурс уже в очереди; Вы можете захотеть изменить этот код, чтобы проверить это и выдать исключение, которое поможет вам определить, где дублируются вызовы Release
(если это действительно так).
Какой-то другой код обращается к очереди _resources
без lock
.
Мое подозрение будет №2, если это действительно то, что вы подразумеваете под дубликатами.