[ACCEPTED]-yield return statement inside a using() { } block Disposes before executing-yield-return
When you call GetAllAnimals
it doesn't actually execute 15 any code until you enumerate the returned 14 IEnumerable in a foreach loop.
The dataContext 13 is being disposed as soon as the wrapper 12 method returns, before you enumerate the 11 IEnumerable.
The simplest solution would 10 be to make the wrapper method an iterator 9 as well, like this:
public static IEnumerable<Animal> GetAllAnimals() {
using (AnimalDataContext dataContext = new AnimalDataContext()) {
foreach (var animalName in dataContext.GetAllAnimals()) {
yield return GetAnimal(animalName);
}
}
}
This way, the using statement 8 will be compiled in the outer iterator, and 7 it will only be disposed when the outer 6 iterator is disposed.
Another solution would 5 be to enumerate the IEnumerable in the wrapper. The 4 simplest way to do that would be to return 3 a List<Animal>
, like this:
public static IEnumerable<Animal> GetAllAnimals() {
using (AnimalDataContext dataContext = new AnimalDataContext()) {
return new List<Animal>(dataContext.GetAllAnimals());
}
}
Note that this loses the benefit 2 of deferred execution, so it will get all 1 of the animals even if you don't need them.
The reason for this is that the GetAllAnimals 14 method doesn't return a colleciton of animals. It 13 returns an enumerator that is capable of 12 returning an animal at a time.
When you return 11 the result from the GetAllAnimals call inside 10 the using block, you just return the enumerator. The 9 using block disposes the data context before 8 the method exits, and at that point the 7 enumerator have not yet read any animals 6 at all. When you then try to use the enumerator, it 5 can not get any animals from the data context.
A 4 workaround is to make the GetAllAnimals 3 method also create an enumerator. That way 2 the using block will not be closed until 1 you stop using that enumerator:
public static IEnumerable<Animal> GetAllAnimals() {
using(AnimalDataContext dataContext = new AnimalDataContext()) {
foreach (Animal animal in dataContext.GetAllAnimals()) {
yield return animal;
}
}
}
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.