2

私は次のコードを持っています:

private void ProcessQueue()
{
    foreach (MessageQueueItem item in GetNextQueuedItem())
        PerformAction(item);
}

private IEnumerable<MessageQueueItem> GetNextQueuedItem()
{
    if (_messageQueue.Count > 0)
        yield return _messageQueue.Dequeue();
}

ProcessQueue が呼び出されると、最初はキューに 1 つの項目があります。PerformAction 中に、_messageQueue にさらに項目を追加します。ただし、foreach ループは最初の項目の後に終了し、後続の項目が追加されたことを認識しません。

どういうわけか、キューの初期状態がyieldによってキャプチャされているように感じます。

誰かが何が起こっているのかを説明し、解決策を提供できますか?

4

3 に答える 3

6

あなたのプログラムはあなたが指示したことを正確に実行しますCount > 0

キューが空になるまでアイテムを返すには、次を試してください。

while (_messageQueue.Count > 0)
于 2010-03-23T22:53:47.103 に答える
1

yield return実際に実行を一時停止し、次のものが要求されるまで偽のリターンを行います (値を生成します)。この場合、カウントが > 0 であるかどうかを確認してから、次の値を生成します。yield return次のステートメントが要求されると、if ステートメントは再度チェックされず、メソッドの終わりである の後の行に戻り、完了します。

于 2010-03-23T23:00:28.293 に答える
0

「利回り」の定義

列挙子オブジェクトに値を提供するため、または反復の終了を通知するために、反復子ブロックで使用されます。

私は構文ステートメントを間違って読んだという優れた記録を持っていますが、これはそれが反復子ブロックにある必要があり、あなたが書いたものはそうではないことを意味すると思います。

おそらくコードを次のように変更してください。

foreeach (MessageQueItem item In GetNextQuedItem()
{
     if (_messageQueue.Count > 0)
     {   
         yield return _messageQueue.Dequeue();
     } else { 
         yield break;
     }

}
于 2010-03-23T23:09:25.543 に答える