Пример #1
0
        public IEnumerator <TDocument> Execute(IConnectionProvider connectionProvider)
        {
            MongoReplyMessage <TDocument> reply = null;

            try
            {
                var count = 0;
                var limit = (_limit >= 0) ? _limit : -_limit;

                reply = GetFirstBatch(connectionProvider);
                foreach (var document in reply.Documents)
                {
                    if (limit != 0 && count == limit)
                    {
                        yield break;
                    }
                    yield return(document);

                    count++;
                }

                while (reply.CursorId != 0)
                {
                    reply = GetNextBatch(connectionProvider, reply.CursorId);
                    foreach (var document in reply.Documents)
                    {
                        if (limit != 0 && count == limit)
                        {
                            yield break;
                        }
                        yield return(document);

                        count++;
                    }

                    if (reply.CursorId != 0 && (_flags & QueryFlags.TailableCursor) != 0)
                    {
                        if ((reply.ResponseFlags & ResponseFlags.AwaitCapable) == 0)
                        {
                            Thread.Sleep(TimeSpan.FromMilliseconds(100));
                        }
                    }
                }
            }
            finally
            {
                if (reply != null && reply.CursorId != 0)
                {
                    try
                    {
                        KillCursor(connectionProvider, reply.CursorId);
                    }
                    catch
                    {
                        // don't throw any exceptions from the finally block
                    }
                }
            }
        }
        /// <summary>
        /// Moves to the next result and returns true if another result is available.
        /// </summary>
        /// <returns>True if another result is available.</returns>
        public bool MoveNext()
        {
            if (disposed)
            {
                throw new ObjectDisposedException("MongoCursorEnumerator");
            }
            if (done)
            {
                // normally once MoveNext returns false the enumerator is done and MoveNext will return false forever after that
                // but for a tailable cursor MoveNext can return false for awhile and eventually return true again once new data arrives
                // so a tailable cursor is never really done (at least while there is still an open cursor)
                if ((cursor.Flags & QueryFlags.TailableCursor) != 0 && openCursorId != 0)
                {
                    done = false;
                }
                else
                {
                    return(false);
                }
            }

            if (!started)
            {
                reply = GetFirst();
                if (reply.Documents.Count == 0)
                {
                    reply = null;
                    done  = true;
                    return(false);
                }
                replyIndex = -1;
                started    = true;
            }

            if (positiveLimit != 0 && count == positiveLimit)
            {
                KillCursor(); // early exit
                reply = null;
                done  = true;
                return(false);
            }

            // reply would only be null if the cursor is tailable and temporarily ran out of documents
            if (reply != null && replyIndex < reply.Documents.Count - 1)
            {
                replyIndex++; // move to next document in the current reply
            }
            else
            {
                if (openCursorId != 0)
                {
                    reply = GetMore();
                    if (reply.Documents.Count == 0)
                    {
                        reply = null;
                        done  = true;
                        return(false);
                    }
                    replyIndex = 0;
                }
                else
                {
                    reply = null;
                    done  = true;
                    return(false);
                }
            }

            count++;
            return(true);
        }