Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB: Disposing a cursor

Excerpt from C# Driver:

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.

A cursor "res" created by calling:

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

doesn't have Dispose method. How do I dispose of it?

like image 501
Andrey Avatar asked May 18 '11 22:05

Andrey


2 Answers

The query returns a MongoCursor<BsonDocument> which doesn't implement IDisposable, so you can't use it in a using block.

The important point is that the cursor's enumerator must disposed, not the cursor itself, so if you were using the cursor's IEnumerator<BsonDocument> directly to iterate over the cursor then you'd need to dispose it, like this:

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

However, you'd probably never do this and use a foreach loop instead. When an enumerator implements IDisposable, as this one does, looping using foreach guarantees its Dispose() method will be called no matter how the loop terminates.

Therefore, looping like this without any explicit disposing is safe:

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

As is evaluating the query with Enumerable.ToList<T>, which uses a foreach loop behind the scenes:

var list = images.Find(query).SetLimit(1).ToList();
like image 66
Chris Fulstow Avatar answered Oct 05 '22 20:10

Chris Fulstow


You don't need to call Dispose on the cursor (indeed MongoCursor doesn't even have a Dispose method). What you need to do is call Dispose on the enumerator returned by the GetEnumerator method of MongoCursor. That happens automatically when you use a foreach statement or any of the LINQ methods that iterate over an IEnumerable. So unless you call GetEnumerator yourself you don't have to worry about callling Dispose either.

like image 30
Robert Stam Avatar answered Oct 05 '22 18:10

Robert Stam