У меня есть блок Iterator, используемый для эмуляции сопрограммы:
public class Event{}
public IEnumerable<Event> Coroutine()
{
// ... do stuff
yield return new Event();
// ... do stuff
yield return new Event();
// ... do stuff
yield return new Event();
// ... do stuff
}
Когда я перечисляю это, могу ли я как-то выяснить в отладчике, какая строка была выполнена последним или на какой строке конечный автомат продолжит работу?
foreach (var event in Coroutine())
{
// <-- breakpoint here
// Can I determine the 'current' line number in Coroutine() ?
// NOTE: This foreach loop is inside a library, I can debug it but not modify it
}
Я знаю, что блок IEnumerable преобразуется в конечный автомат с помощью компилятора .net, и в настоящий момент нет никакого StackFrame этого блока, в то время как программа остановлена за пределами блока. Но где-то конечный автомат должен хранить, где продолжить выполнение. Могу ли я получить доступ к этой информации?
Фон: зачем мне это?
Я пытаюсь отладить симуляцию с помощью Dessert Framework (аналогично SimPy ).
В этой среде, к лучшему или худшему, все смоделированные задачи реализованы в виде сопрограмм с использованием yield return
блоков итераторов.
При отладке такого моделирования важно выяснить текущее состояние каждой моделируемой задачи.
В приведенном выше примере я, конечно, могу просто посчитать, сколько раз была достигнута точка останова, и точно знать, где находится мой блок итератора.
Но случай, который я пытаюсь отладить, состоит в том, что несколько сопрограмм работают одновременно, генерируя и потребляя ресурсы и ожидая завершения друг друга. IEnumerables используются не моим кодом, а самой платформой.