TL; DR - существует ли «рекурсивный» [DebuggerStepThrough]
?
Есть ли атрибут, который я могу использовать в методе, чтобы при использовании Отладка> Разбить все в неактивной форме WinForms и затем перейти в Application.Run()
, чтобы в этом методе не возникала точка останова или что-то вызываемое, когда событие вызывает этот метод?
Вот простой пример кода в качестве иллюстрации проблемы¹:
static void Main() {
Application.Run(new MyForm()); //I step (F11) into here to wait for events of interest
}
string GetSome {
get { //I don't want to wind up on a breakpoint here
return "Some"; //as a result of OnActivated() being called!
} //But I *DO* want to be able to step in here otherwise,
} //(e.g. as a result of OnClick() being called.²
[DebuggerStepThrough] //Not interested in this event or anything it calls
protected override void OnActivated(EventArgs e){
string come = GetSome;
}
protected override void OnClick(EventArgs e){ //But I *AM* interested in this event
string come = GetSome;
}
Что я делаю: Как только моя форма WinForms полностью инициализирована, получила фокус и теперь свободна (нет сообщений в очереди в цикле сообщений) (маркер 1) , я приостановить бездействующую форму с помощью Debug> Break All . Форма находится в бездействующем цикле, поэтому отладчик показывает самый верхний кадр стека в виде [Внешний код] , причем предыдущий кадр стека представляет собой строку Application.Run()
. Затем я нажал F11 (Step Into). Цикл сообщений формы возобновляется, и форма снова активируется и получает фокус. (маркер 2) Отладчик теперь приостанавливается, как только управляемый кадр поднимается вверху стека - например, когда происходит одно из событий в приведенном выше коде. (маркер 3) При повторной активации формы вызывается OnActivated()
.
Желаемое поведение:
Я хочу, чтобы отладчик игнорировал OnActivated()
и все, что бы он ни вызывал. После того, как я нажму на возобновленную форму, я хочу, чтобы отладчик сделал паузу на OnClick()
, так как отладчик ожидает, пока управляемый кадр не достигнет вершины стека.
Что на самом деле происходит:
Отладчик игнорирует OnActivated()
(поскольку он помечен как [DebuggerStepThrough]
) - хорошо , но останавливается в GetSome
getter - bad . На данный момент:
- Если я пройду через геттер
GetSome
, форма снова активируется, и я вернусь к маркер 2 , и я в цикле.
- Если я выхожу (Shift + F11) из геттера
GetSome
, это имеет тот же эффект, что и нажатие клавиши F5 - выполнение программы полностью возобновляется, и отладчик больше не ожидает паузы в следующем кадре управляемого стека , Я вернулся на маркер 1 .
Интересно, что отладчик фактически игнорирует параметр «Отладка> Параметры> Отладка> Общие> Свойства и операторы перехода» в маркер 3 . Если при входе в форму я вхожу в (F11) Application.Run()
вручную, с включенным «Свойства перехода и операторы» , отладчик не не приостанавливает работу геттера GetSome
из OnActivated()
вызывается!
anywhere В коде нет явных точек останова. В реальном коде, над которым я работаю, я пытаюсь заставить отладчик игнорировать только несколько определенных событий перерисовки (и любые методы и средства доступа, которые они вызывают из других классов), в то же время имея возможность использовать «Break All + F11» как ярлык для перехода к следующему событию (существует множество возможностей) без необходимости устанавливать явную точку останова для каждого из них.
² Причина, по которой я не могу просто пометить все другие методы, которые «неинтересные» события также вызывают атрибутом [DebuggerStepThrough]
, двояка: несколько «неинтересных» событий, которые у меня есть, вызывают сотни других методов - это много рефакторинга и видимых помех для добавления; и так как, конечно, я бы потерял способность обходить эти методы, когда мне это действительно нужно при отладке.