Отладка IEnumerable: получить номер текущей строки блока Iterator. - PullRequest
0 голосов
/ 04 сентября 2018

У меня есть блок 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 используются не моим кодом, а самой платформой.

...