MongoDB: удаление курсора - PullRequest
7 голосов
/ 19 мая 2011

Выдержка из драйвера C #:

It is important that a cursor cleanly release any resources it holds. The key to guaranteeing this is to make sure the Dispose method of the enumerator is called. The foreach statement and the LINQ extension methods all guarantee that Dispose will be called. Only if you enumerate the cursor manually are you responsible for calling Dispose.

Курсор "res", созданный путем вызова:

var res = images.Find(query).SetFields(fb).SetLimit(1);

не имеет Dispose метода. Как мне избавиться от этого?

Ответы [ 2 ]

9 голосов
/ 19 мая 2011

Запрос возвращает MongoCursor<BsonDocument>, который не реализует IDisposable, поэтому вы не можете использовать его в блоке using.

Важным моментом является то, что перечислитель курсора должен располагаться, а не сам курсор, поэтому, если вы использовали курсор IEnumerator<BsonDocument> непосредственно для перебора курсора, то вам нужно было бы его расположить, как это:

using (var iterator = images.Find(query).SetLimit(1).GetEnumerator())
{
    while (iterator.MoveNext())
    {
        var bsonDoc = iterator.Current;
        // do something with bsonDoc
    }
}

Однако вы, вероятно, никогда не сделаете этого и вместо этого будете использовать цикл foreach. Когда перечислитель реализует IDisposable, как это происходит, цикл с использованием foreach гарантирует , что его Dispose() метод будет вызван независимо от того, как завершится цикл.

Следовательно, циклическая обработка без явного удаления безопасна:

foreach (var bsonDocs in images.Find(query).SetLimit(1))
{
    // do something with bsonDoc                
}

As оценивает запрос с помощью Enumerable.ToList , который использует зацикленный цикл за кадром:

var list = images.Find(query).SetLimit(1).ToList();
3 голосов
/ 19 мая 2011

Вам не нужно вызывать Dispose для курсора (действительно, MongoCursor даже не имеет метода Dispose). Вам нужно вызвать Dispose для перечислителя, возвращаемого методом GetEnumerator MongoCursor. Это происходит автоматически, когда вы используете оператор foreach или любой из методов LINQ, которые перебирают IEnumerable. Поэтому, если вы сами не вызовете GetEnumerator, вам не придется беспокоиться о вызове Dispose.

...