恢复C#异步方法时,System.Diagnostics.StackTrace中缺少Visual Studio 2017调用堆栈中可见的堆栈帧
我有以下使用asyc方法的简单C#代码片段:恢复C#异步方法时,System.Diagnostics.StackTrace中缺少Visual Studio 2017调用堆栈中可见的堆栈帧,c#,.net,visual-studio,stack,stack-trace,C#,.net,Visual Studio,Stack,Stack Trace,我有以下使用asyc方法的简单C#代码片段: class SUT { public async Task<int> GetValue() { await Task.Delay(1000); return 42; } } class Program { static async Task<int> CallAsync() { SUT sut = new SUT(); i
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();
}
}
类SUT
{
公共异步任务GetValue()
{
等待任务。延迟(1000);
返回42;
}
}
班级计划
{
静态异步任务CallAsync()
{
SUT SUT=新SUT();
int result=wait sut.GetValue();
返回结果;
}
静态void Main(字符串[]参数)
{
CallAsync().GetAwaiter().GetResult();
}
}
我将断点放在“return 42”语句上,观察Visual Studio调用堆栈和从System.Diagnostics.StackTrace()获得的StackTrace。如下图所示,VS调用堆栈窗口中有一些帧未显示在堆栈跟踪中:
是否有一种方法可以使用System.Diagnostics.StackTrace获取堆栈跟踪,就像在Visual Studio调用堆栈窗口中观察到的那样?好吧,如果您想一想StackTrace是什么,它实际上是一个调用方法的堆栈。其中最深的方法位于堆栈顶部。 如果您考虑以下程序,主呼叫先呼叫,先呼叫秒,第二呼叫第三。p>
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
方法的第一行中放置断点时,调用堆栈与上面类似,因为代码一直同步执行到该点。但是,该方法实际上是在调用wait Task.Delay
时返回,将第一个方法从堆栈中弹出。在此之后,访问第三行的唯一方法是框架在第三行创建“continuation”。现在可能很清楚,这个延续必须由我们自己的代码以外的东西调用,这就是为什么callstack包含所有这些奇怪的方法
因此,您无法获得仅包含代码的调用堆栈,因为它已不存在,但在Visual Studio设置中,您可以启用。在最后一个示例中,当您在First
方法的第3行中断时,可能会出现这种情况。不完全是你要找的,但很接近
(VSCode截图)