【问题标题】:MongoDB: Disposing a cursorMongoDB:处理游标
【发布时间】:2011-05-18 22:56:44
【问题描述】:

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

【问题讨论】:

    标签: c# mongodb mongodb-.net-driver


    【解决方案1】:

    查询返回一个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                
    }
    

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

    var list = images.Find(query).SetLimit(1).ToList();
    

    【讨论】:

    • 调用 FirstOrDefault() 而不是 ToList() 怎么样 - 这是否保证在枚举器上调用 Dispose?因为这就是我使用它的方式,我想确保我正确使用它。
    • 是的,这也很好,它会这样做:using (var enumerator = source.GetEnumerator()) { if (enumerator.MoveNext()) return enumerator.Current; }
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多