Ну, если вы подумаете о том, что такое трассировка стека, это буквально стек вызванных методов.Где самый глубокий метод находится на вершине стека.Если вы рассмотрите следующую программу, Main вызывает первый, первый вызов второй, а второй вызов третий.
class Program
{
static void Main(string[] args) => First();
static void First() => Second();
static void Second() => Third();
static void Third() => Console.WriteLine("Third method.");
}
Когда вы находитесь в третьем методе, ваш стек будет выглядеть так (оставаясь вершиной стека):
Third - Second - First - Main
Тогда когдаТретий завершен, третий извлечен из стека и трассировка выглядит следующим образом:
Second - First - Main
и т. Д.и т. д.
Теперь это легко понять, когда не используется асинхронный код.Итак, давайте посмотрим, что происходит в вашем примере:
static void Main(string[] args) => First().Wait();
static async Task First()
{
Console.WriteLine("First method starting");
await Task.Delay(1000);
Console.WriteLine("First method finishing.");
}
Когда вы ставите точку останова в первой строке метода First
, стек вызовов аналогичен описанному выше, поскольку код, выполняемый синхронно до этоготочка.Однако метод на самом деле возвращает при вызове await Task.Delay
, выталкивая метод First
из стека.Единственный способ получить доступ к третьей строке после этого - это если фреймворк создает «продолжение» в третьей строке.Теперь может быть ясно, что это продолжение должно вызываться чем-то отличным от нашего собственного кода, и именно поэтому callstack содержит все эти странные методы.
Таким образом, вы не можете получить callstack, содержащий только ваш код, потому чтоон больше не существует, но в настройках Visual Studio вы можете включить Just My Code .Это может выглядеть так, когда вы разбиваете строку 3 метода First
в последнем примере.Не совсем то, что вы ищете, но близко.
(Скриншот из VSCode)