Recientemente inicié una aplicación WPF. Lo conecté a una base de datos BaseX (basada en XML) y recuperé aproximadamente un millón de entradas de él. Quería para repetir las entradas, calcular algo para cada entrada y luego escribir que de vuelta a la base de datos:Iterar colecciones grandes en C#: Tomar mucho tiempo
IEnumerable<Result> resultSet = baseXClient.Query("...", "database");
foreach (Result result in resultSet)
{
...
}
El problema: no se alcanza nunca el interior del foreach. el método Query() regresa bastante rápido, pero cuando se alcanza el foreach C# parece hacer ALGO con la colección, el código no continúa durante un tiempo muy largo (al menos 10 minutos, nunca lo deje funcionar). ¿Qué está pasando aquí? Traté de limitar el número de elementos recuperados. Al recuperar 100.000 resultados, ocurre lo mismo, pero el código continúa después de unos 10-20 segundos. Al recuperar el millón de resultados completos, C# parece estar estancado para siempre ...
¿Alguna idea? respecto
Editar: por qué ocurre esto Como algunos de ustedes han señalado, la razón de este comportamiento parece ser que la consulta es en realidad sólo se evalúa cuando MoveNext()
en el interior del enumerador Enumerable se llama. Parece que mi base de datos no puede devolver un valor a la vez, sino que devuelve todo el millón de conjunto de datos a la vez. Intentaré cambiar a otra base de datos (Apache Lucene, si es posible, ya que tiene un buen soporte de búsqueda de texto completo) y editar esta publicación para hacerle saber si cambió algo.
PD: Sí, soy consciente de que un millón de resultados es mucho. Esto no es para uso en vivo, es solo un paso para preparar los datos. Si bien no esperaba que el código se ejecutara en unos pocos segundos, todavía me sorprendió ver TAL rendimiento deficiente en la base de datos.
Edit: The Solution Así que migré la base de datos XML a Apache Lucine. ¡Funciona de maravilla! Por supuesto, Lucine es una base de datos basada en texto que no es adecuada para todos los casos de uso, pero para mí funcionó de maravilla. Puede iterar más de un millón de entradas en unos pocos segundos, se obtiene una entrada por ciclo: ¡funciona extremadamente bien!
[ejecución diferida] (http://blogs.msdn.com/b/charlie/archive/2007/12/09/deferred-execution.aspx). – Adam
@codesparkle, buena información, pero me pregunto por qué parece que toda su consulta debe ejecutarse antes de que se devuelva el primer elemento. –
Considere publicar más código y una muestra menor de los datos. – EKS