Contesto: ho un sacco di stringhe che sto ricevendo da un database e voglio restituirle. Tradizionalmente, sarebbe qualcosa di simile:C# IEnumerator/struttura di rendimento potenzialmente negativa?
public List<string> GetStuff(string connectionString)
{
List<string> categoryList = new List<string>();
using (SqlConnection sqlConnection = new SqlConnection(connectionString))
{
string commandText = "GetStuff";
using (SqlCommand sqlCommand = new SqlCommand(commandText, sqlConnection))
{
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlConnection.Open();
SqlDataReader sqlDataReader = sqlCommand.ExecuteReader();
while (sqlDataReader.Read())
{
categoryList.Add(sqlDataReader["myImportantColumn"].ToString());
}
}
}
return categoryList;
}
Ma poi ho capire il consumatore sta andando a voler scorrere gli elementi e non si preoccupa molto altro, e mi piacerebbe non me stesso in scatola ad una lista, di per sé, quindi se restituisco un IEnumerable tutto è buono/flessibile. Stavo pensando che potrei usare un "ritorno rendimento" tipo di progetto per gestire questa situazione ... qualcosa di simile:
public IEnumerable<string> GetStuff(string connectionString)
{
using (SqlConnection sqlConnection = new SqlConnection(connectionString))
{
string commandText = "GetStuff";
using (SqlCommand sqlCommand = new SqlCommand(commandText, sqlConnection))
{
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlConnection.Open();
SqlDataReader sqlDataReader = sqlCommand.ExecuteReader();
while (sqlDataReader.Read())
{
yield return sqlDataReader["myImportantColumn"].ToString();
}
}
}
}
Ma ora che sto leggendo un po 'di più su rendimento (su siti come questo .. .msdn non sembra menzionarlo), è apparentemente un pigro valutatore, che mantiene lo stato del populatore in giro, in previsione di qualcuno che chiede il valore successivo, e quindi lo esegue solo finché non restituisce il valore successivo.
Questo sembra buono nella maggior parte dei casi, ma con una chiamata DB, questo suona un po 'rischioso. Come un esempio un po 'forzato, se qualcuno chiede un IEnumerable da quello che sto compilando da una chiamata DB, ne riceve metà e poi si blocca in un loop ... per quanto posso vedere la mia connessione DB sta andando rimanere aperti per sempre.
Suona come chiedere guai in alcuni casi se l'iteratore non finisce ... mi manca qualcosa?
Grazie per la modifica, Jon ... questo è quello che ho per la digitazione al volo. – Beska
Finché il consumatore chiama 'Dispose' su IEnumerator, sei al sicuro. Vedi il mio post qui sotto. – tofi9