У меня есть необычный случай, когда у меня есть очень простое Исключение, которое выдается и ловится тем же методом. Не перебрасывается (обычный тип проблем, которые есть у наивных программистов). И все же его StackFrame содержит только один текущий метод. Вот как это выглядит:
at (my class).MyMethod() in C:\(my file path and line)
На самом деле в стеке вызовов отладчика VS2010, вероятно, есть 30 методов, ведущих через полдюжины различных сборок. Кажется невозможным для всего этого быть оптимизированным. Более того, этот код встроен в режим отладки, без оптимизации , для .NET 4. У меня даже есть (на основе http://msdn.microsoft.com/en-us/library/9dd8z24x.aspx) .ini файлов (включая один с именем [app] .vshost.ini). ) в той же папке, содержащей:
[.NET Framework Debugging Control]
GenerateTrackingInfo=1
AllowOptimize=0
Кроме того, вызовы методов не находятся в конце методов, поэтому оптимизация хвостовой рекурсии представляется маловероятной.
Относительно того, как он вызывается: нет никакого отражения в стеке вызовов, нет Invoke () или BeginInvoke () любого вида. Это просто длинная цепочка звонков от нажатия кнопки. Обработчик кликов составляет около 10 вызовов на стек вызовов. Ниже у вас есть обычный WndProc, NativeWindow.Callback, собственные / управляемые переходы и цикл сообщений. В конечном итоге это происходит внутри вызова ShowDialog (), который запускается из сборки C # EXE.
Теперь я обнаружил, что могу создавать экземпляры класса StackTrace в своем обработчике перехвата, и если я передаю объект Exception, стек вызовов также становится коротким. Если вместо этого я просто вызываю новый StackTrace () без аргументов, это приводит к полному стеку вызовов.
Я использовал Reflector при попытке отладки внутренних элементов класса Exception и создания его стека вызовов, но я не смог установить точки останова в Exception или в StackTrace. Я мог бы установить их в Environment.GetStackTrace (), и этот метод (который вызывает исключение), по-видимому, не вызывается во время процесса создания и создания, но я не знаю, действительно ли отладчик работает правильно. (Этот метод запускается для некоторых других вещей, поэтому я не уверен, что с ним делать.)
Вот выдержка из метода:
private void MyMethod()
{
...
try
{
throw new ApplicationException("Test failure");
}
catch (Exception e)
{
StackTrace stackTrace1 = new StackTrace(e);
StackTrace stackTrace2 = new StackTrace(e, false);
StackTrace stackTrace3 = new StackTrace(e, true);
StackTrace stackTrace4 = new StackTrace();
string STs = stackTrace1.ToString() + "\n---\n"
+ stackTrace2.ToString() + "\n---\n"
+ stackTrace3.ToString() + "\n---\n"
+ stackTrace4.ToString();
Log(EventSeverity.Debug, STs);
...
}
}
Это действительно довольно просто: бросить исключение, поймать и зарегистрировать его.
Я получаю те же результаты либо в отладчике, либо в автономном режиме - стек вызовов из одной строки. И я знаю, что видел эту проблему в другом месте нашей базы кода. Ранее я предполагал, что это было связано с повторным вызовом исключений, но во многих случаях мы регистрируем его прямо в начальном блоке catch. Я совершенно сбит с толку, и весь поиск в Интернете, который я сделал, ничего не дал.
Это слишком много, чтобы добавить в качестве комментария к предоставленному ответу, но вот еще немного информации:
Теперь я вижу, что это поведение обсуждается в
http://dotnetthoughts.wordpress.com/2007/10/27/where-did-my-exception-occur/ и что это на самом деле описано в http://msdn.microsoft.com/en-us/library/system.exception.stacktrace.aspx (хотя я думаю, что можно легко пропустить то, что они там говорят).
Так что я думаю, что мое "решение" будет немного хитом или промахом. У нас есть центральный метод, который мы обычно вызываем для форматирования исключений. Внутри этого метода я создам новый StackTrace () как с объектом Exception, так и без него. Затем я буду искать метод, который находится в нижней части трассировки стека Исключения, и отображать все, что ниже, в новом StackTrace (), указывая, что он был вызван этой серией вызовов.
Недостатком, конечно, является то, что если этот метод не используется, информация не будет там. Но я должен был ожидать какого-то изменения кода где-то.