恢复 C# 异步方法时,System.Diagnostics.StackTrace 中缺少 Visual Studio 2017 调用堆栈中可见的堆栈帧
Posted
技术标签:
【中文标题】恢复 C# 异步方法时,System.Diagnostics.StackTrace 中缺少 Visual Studio 2017 调用堆栈中可见的堆栈帧【英文标题】:Stack frames visible in Visual Studio 2017 Call Stack are missing in System.Diagnostics.StackTrace when resuming C# async method 【发布时间】:2019-08-10 21:05:50 【问题描述】:我有以下使用 asyc 方法的简单 C# 代码 sn-p:
class SUT
public async Task<int> GetValue()
await Task.Delay(1000);
return 42;
class Program
static async Task<int> CallAsync()
SUT sut = new SUT();
int result = await sut.GetValue();
return result;
static void Main(string[] args)
CallAsync().GetAwaiter().GetResult();
我在“return 42”语句上放置断点并观察 Visual Studio 调用堆栈和从 System.Diagnostics.StackTrace() 获得的 StackTrace。在 VS 调用堆栈窗口中有一些可见的帧,这些帧没有出现在 StackTrace 中,如下图所示: StackTrace is missing frames from VS Call Stack window
有没有办法使用 System.Diagnostics.StackTrace 完全按照在 Visual Studio 调用堆栈窗口中观察到的方式获取堆栈跟踪?
【问题讨论】:
【参考方案1】:好吧,如果你想一想堆栈跟踪是什么,它实际上就是一堆被调用的方法。最深的方法位于堆栈顶部。 如果你考虑下面的程序,Main 首先调用,first 调用第二个,second 调用第三个。
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
然后当 Third 完成时,Third 会从堆栈中弹出,跟踪如下所示:
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
方法从堆栈中弹出。之后可以访问第三行的唯一方法是框架在第三行创建“延续”。现在可能很清楚,这个延续必须由我们自己的代码以外的其他东西调用,这就是为什么调用堆栈包含所有这些奇怪的方法。
因此您无法获得仅包含您的代码的调用堆栈,因为它不再存在,但在 Visual Studio 设置中,您可以启用Just My Code。当您在上一个示例中的 First
方法的第 3 行中断时,可能看起来像这样。不完全是您正在寻找的东西,但很接近。
(来自 VSCode 的屏幕截图)
【讨论】:
以上是关于恢复 C# 异步方法时,System.Diagnostics.StackTrace 中缺少 Visual Studio 2017 调用堆栈中可见的堆栈帧的主要内容,如果未能解决你的问题,请参考以下文章
在恢复C#异步方法时,System.Diagnostics.StackTrace中缺少Visual Studio 2017调用堆栈中可见的堆栈帧