Mongo 2.4.3 で MongoDB C# ドライバー 1.8.1.20 を使用しています。次の無限ループを使用して、上限のあるコレクションから新しいメッセージをポーリングし、受信したときにそれらを処理します (tailable カーソルと await データを使用)。ほとんどの場合は機能しますが、実稼働環境では、時々 enumerator.MoveNext() の呼び出しがブロックされて返されないようです。これによりループが停止し、アプリケーションが更新を受信しなくなります。接続が予期せず閉じられたときに発生しているようです。
while (true)
{
try
{
using (MongoCursorEnumerator<QueueMessage> enumerator = GetCursor())
{
while (!enumerator.IsDead)
{
while (enumerator.MoveNext()) // This is blocking forever when connection is temporarily lost
this.processMessage(enumerator.Current);
}
}
}
catch (Exception ex)
{
Trace.TraceError("Error in the ReceiveCore loop: " + ex.ToString());
}
}
GetCursor 関数はこれを行います。
cursor = (MongoCursorEnumerator<QueueMessage>)collection
.FindAllAs<QueueMessage>()
.SetFlags(QueryFlags.AwaitData | QueryFlags.TailableCursor | QueryFlags.NoCursorTimeout)
.SetSortOrder(SortBy.Ascending("$natural"))
.GetEnumerator();
それが永久にブロックされるのはなぜですか?また、完了できない場合に(おそらくタイムアウトにより)例外がスローされるようにするにはどうすればよいですか?