Ни одна из стандартных коллекций .NET по умолчанию не поддерживает потоки. Они не могут быть доступны одновременно без какого-либо барьера памяти, препятствующего одновременному доступу.
В вашем случае семафор запрещает доступ более чем пяти потокам к resources
, но ничто не мешает любому из этих пяти одновременно работающих потоков вводить Dequeue()
или Enqueue()
одновременно .Вполне возможно, что среди этих потоков возникает редкое состояние гонки, которое приводит к повреждению очереди.Вы действительно должны поставить блокировку вокруг самой очереди resources
.
Я бы также посоветовал вам выполнить тест внутри блокировки , чтобы убедиться, что в очереди все еще есть элементы для удаления, прежде чемВы пытаетесь позвонить Dequeue()
.Однако, поскольку я не знаю специфики работы вашего кода, я оставляю вам решать, имеет ли это отношение.
Semaphore smphSync = new Semaphore(0, 5);
Queue<IResource> resources;
private _lockObj = new object();
private IResource GetResource()
{
smphSync.WaitOne();
lock( _lockObj )
{
IResource res = resources.Dequeue();
return res;
}
}
private ReleaseResource(IResource res)
{
lock( _lockObj )
{
resources.Enqueue(res);
}
smphSync.Release();
}