Я пытаюсь создать структуру данных вокруг стека, которая блокируется до тех пор, пока в стеке не появится доступный элемент. Я пытался использовать AutoResetEvent
, но, кажется, неправильно понял, как работает этот процесс синхронизации. По сути, глядя на следующий код, я пытаюсь вытолкнуть из стека, когда ничего не доступно.
Кажется, что AutoResetEvent
ведет себя как семафор. Это правильно? Могу я просто избавиться от Set()
в BlockingStack.Get()
и покончить с этим? Или это приведет к ситуации, когда я использую только один из элементов стека?
public class BlockingStack
{
private Stack<MyType> _internalStack;
private AutoResetEvent _blockUntilAvailable;
public BlockingStack()
{
_internalStack = new Stack<MyType>(5);
_blockUntilAvailable = new AutoResetEvent(false);
for (int i = 0; i < 5; ++i)
{
var obj = new MyType();
Add(obj);
}
}
public MyType Get()
{
_blockUntilAvailable.WatiOne();
lock (_internalStack)
{
var obj = _internalStack.Pop();
if (_internalStack.Count > 0)
{
_blockUntilAvailable.Set(); // do I need to do this?
}
return obj;
}
}
public void Add(MyType obj)
{
lock (_internalStack)
{
_internalStack.Push(obj);
_blockUntilAvailable.Set();
}
}
}
Мое предположение заключалось в том, что AutoResetEvent
сбрасывается для всех ожидающих потоков, когда один из них завершает вызов функции WaitOne()
. Тем не менее, кажется, что поступает несколько потоков. Если только я где-то не напутал свою логику.
EDIT: это для Silverlight.