Я обнаружил ситуацию, когда блок finally не вызывается.
К точке:
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();
}
}
}
И результат:
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!
Итак, похоже, что если кто-то использует мой метод yield и работает с ним вручную, используя перечислители (не с foreach), то мой блок finally никогда не может быть вызван.
Есть ли способ убедиться, что мой метод завершает свои ресурсы? И это ошибка в «синтаксическом сахаре выхода» или он работает так, как должен быть?