![](/img/trans.png)
[英]C# Portable Class Library Equivalent of System.Diagnostics.StackTrace
[英]Stack frames visible in Visual Studio 2017 Call Stack are missing in System.Diagnostics.StackTrace when resuming C# async method
我有以下使用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();
int result = await sut.GetValue();
return result;
}
static void Main(string[] args)
{
CallAsync().GetAwaiter().GetResult();
}
}
我將斷點放在“return 42”語句中,並觀察Visual Studio Call Stack和從System.Diagnostics.StackTrace()獲得的StackTrace。 在VS Call Stack窗口中可以看到一些未在StackTrace中顯示的幀,如下圖所示: StackTrace缺少來自VS Call Stack窗口的幀
有沒有辦法使用System.Diagnostics.StackTrace完全按照在Visual Studio調用堆棧窗口中觀察到的方式獲取堆棧跟蹤?
好吧,如果你考慮堆棧跟蹤是什么,它就是一堆被稱為方法的文件。 最深層的方法位於堆棧頂部。 如果你考慮以下程序,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方法時,你的堆棧將如下所示(左邊是堆棧的頂部):
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
方法的第一行中放置斷點時,callstack與上面類似,因為代碼同步執行到該點。 但是,該方法實際上在調用時返回 await Task.Delay
,從堆棧彈出First
方法。 在此之后可以訪問第三行的唯一方法是框架在第三行創建“延續”。 現在可能很清楚,這個延續必須由我們自己的代碼以外的東西調用,這就是callstack包含所有這些奇怪方法的原因。
因此,您無法獲得僅包含代碼的callstack,因為它不再存在,但在Visual Studio設置中,您可以啟用Just My Code 。 當您在上一個示例中的First
方法的First
3行中斷時,這可能看起來像這樣。 不完全是你想要的,但接近。
(來自VSCode的截圖)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.