スタックにアイテムが利用可能になるまでブロックするスタックの周りのデータ構造を設計しようとしています。私は使ってみましたAutoResetEvent
が、その同期プロセスがどのように機能するかを誤解したと思います。基本的に、次のコードを見て、利用可能なものがないときにスタックからポップしようとしています。
AutoResetEvent
はセマフォのように動作しているようです。あれは正しいですか?私はただそれを取り除き、それSet()
で終わらせることができBlockingStack.Get()
ますか?または、スタックアイテムの1つだけを使用している状況になりますか。
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()
ただし、複数のスレッドが入っているようです。どこかでロジックを台無しにしない限り。
編集:これはSilverlight用です。