I found a situation when finally block is not called.
To the point:
using System;
using System.Collections.Generic;
using System.Threading;
using System.ComponentModel;
class MainClass{
static IEnumerable<int> SomeYieldingMethod(){
try{
yield return 1;
yield return 2;
yield return 3;
}finally{
Console.WriteLine("Finally block!");
}
}
static void Main(){
Example(7);
Example(2);
Example(3);
Example(4);
}
static void Example(int iterations){
Console.WriteLine("\n Example with {0} iterations.", iterations);
var e = SomeYieldingMethod().GetEnumerator();
for (int i = 0; i< iterations; ++i) {
Console.WriteLine(e.Current);
e.MoveNext();
}
}
}
And the result:
Example with 7 iterations.
0
1
2
3
Finally block!
3
3
3
Example with 2 iterations.
0
1
Example with 3 iterations.
0
1
2
Example with 4 iterations.
0
1
2
3
Finally block!
So, it looks like if someone is using my yielding method and works with it manually using enumerators (not with foreach) then my finally block can never be called.
Is there any way to ensure that my method finalizes it's resources? And is that a bug in "yield syntactic sugar" or does it work as it supposed to be?