Recentemente ho avviato un'applicazione WPF. L'ho collegato a un database BaseX (basato su XML) e recuperato circa un milione di voci da esso. Volevo iterare le voci, calcolare qualcosa per ogni voce e poi scrivere che nel database:Iterazione su grandi raccolte in C#: impiega molto tempo
IEnumerable<Result> resultSet = baseXClient.Query("...", "database");
foreach (Result result in resultSet)
{
...
}
Il problema: L'interno del foreach non viene mai raggiunto. il metodo Query() ritorna abbastanza veloce, ma quando viene raggiunto il foreach C# sembra fare SOMETHING con la collezione, il codice non continua per un tempo molto lungo (almeno 10 minuti, non lasciarlo mai più funzionare). Cosa sta succedendo qui? Ho provato a limitare il numero di elementi recuperati. Quando si recuperano 100.000 risultati, si verifica la stessa cosa ma il codice continua dopo circa 10-20 secondi. Quando recuperi l'intero milione di risultati, C# sembra essere bloccato per sempre ...
Qualche idea? saluti
Modifica: perché questo sta accadendo Come alcuni di voi hanno sottolineato, la ragione di questo comportamento sembra essere che la query è in realtà valutata solo quando MoveNext()
sul Enumeratore all'interno del Enumerable si chiama. Il mio database sembra non essere in grado di restituire un valore alla volta, ma restituisce invece l'intero milione di set di dati contemporaneamente. Cercherò di passare ad un altro database (Apache Lucene, se possibile, dato che ha un buon supporto per la ricerca fulltext) e modificare questo post per farti sapere se ha cambiato qualcosa.
PS: Sì, sono consapevole che un milione di risultati è molto. Questo non è pensato per l'uso dal vivo, è solo un passo per la preparazione dei dati. Mentre non mi aspettavo che il codice potesse essere eseguito in pochi secondi, ero ancora sorpreso di vedere prestazioni scadenti nel database.
Modifica: la soluzione Così ho migrato il database XML ad Apache Lucine. Funziona come un fascino! Ovviamente Lucine è un database testuale che non è adatto per ogni caso d'uso, ma per me ha funzionato a meraviglia. Può iterare oltre un milione di voci in pochi secondi, viene recuperata una voce per ciclo - funziona molto bene!
[esecuzione differita] (http://blogs.msdn.com/b/charlie/archive/2007/12/09/deferred-execution.aspx). – Adam
@codesparkle, buone informazioni, ma mi chiedo perché sembra che la sua intera query debba essere eseguita prima che il primo elemento venga restituito. –
Si prega di prendere in considerazione la pubblicazione di più codice e un campione minore dei dati. – EKS