I have following code. The query take some 30 seconds to execute. I found that the top using block is called every time for each try to enumerate the iterator. Which mean query is executed for each call to MoveNext in enumerator.
So why lazy evaluation reintialize using over and over again. I know the work around but i need to understand the purpose of this.
private IEnumerable<FriendProfile> GetProfiles() {
var query = @"
SELECT VirtualNumber, City, Gender, Nick, Age
FROM Profiles
WHERE Not VirtualNumber In ( SELECT VirtualNumber FROM Messages)
ORDER BY Id DESC;";
using (var con = GetConnection()) {
using (var cmd = dbconnection.CreateCommand()) {
cmd.CommandText = query;
var reader = cmd.ExecuteReader();
while (reader.Read()) {
var fp = new FriendProfile();
fp.VirtualNumber = reader.GetString(0);
fp.City = reader.GetString(1);
fp.Gender = reader.GetString(2);
fp.Nick = reader.GetString(3);
fp.Age = reader.GetInt16(4).ToString();
yield return fp;
}
}
}
}
foreach(var fp in GetProfiles()){
.... //foreach item using(){} in GetProfile() is reinitializes. All usings blocks
}
I’m not 100% sure which using block you are referring to, but if I have understood correctly, what you have said should not be happening. The
yieldwill return control of execution from theGetProfiles()method, but the code after theyield(ie. the end of theusingblocks) will not be executed until thewhilecondition isfalse.Here is a simple example that should demonstrate this behaviour:
Using this class to show when the end of the
usingblock executes:and this code:
The output is:
This shows that the
usingblocks do not exit until theforloop exits.