7

摘自 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方法。我该如何处理它?

4

2 回答 2

9

该查询返回 a MongoCursor<BsonDocument>which doesn't implement 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                
}

正如使用Enumerable.ToList<T>评估查询一样,它在后台使用 foreach 循环:

var list = images.Find(query).SetLimit(1).ToList();
于 2011-05-19T01:46:34.083 回答
3

您不需要在光标上调用 Dispose (实际上 MongoCursor 甚至没有 Dispose 方法)。您需要做的是对 MongoCursor 的 GetEnumerator 方法返回的枚举器调用 Dispose。当您使用 foreach 语句或任何迭代 IEnumerable 的 LINQ 方法时,这种情况会自动发生。因此,除非您自己调用 GetEnumerator,否则您也不必担心调用 Dispose。

于 2011-05-19T00:16:49.163 回答