我正在閱讀一些來自UWP應用程序(C#,使用.NET Native編譯)的崩潰報告,並且我很難理解堆棧跟蹤中使用的確切語法/格式。 我試過在互聯網上尋找一些指南,但我沒有拿出任何有用的東西。如何正確讀取/解釋原始C#堆棧跟蹤?
以下是幾個例子:
1)
MyProject.ViewModels.SomeViewModel.<OnLogin>d__69.MoveNext()
OnLogin
是在SomeViewModel
的方法的名稱,因此它爲什麼角括號內?"ClassName".<"MethodName>..."
是指示實例方法的常用方法嗎?- 我知道C#編譯器將
await
調用之間的代碼塊變成匿名方法,並使用延續來調度它們,所以我猜d__69
表示當前方法內部的異步延續。- 'd'代表什麼?
- 這些數字是隨機的嗎?我的意思是,該方法沒有69
await
調用,所以我猜這些數字不是順序的。是否有可能從堆棧跟蹤中的數字中找出原始方法中的確切部分?
- 這是什麼
MoveNext()
方法在最後?它需要什麼類型的?
2)
MyProject.UserControls.SomeControl.<.ctor>b__0_0
- 我知道
.ctor
代表對象的構造函數,看着我發現了代碼,b__0_0
代表一個匿名事件處理程序裏面加構造函數,如下所示:SomeEvent += (s, e) => Foo();
。- 'b'代表什麼?
- 爲什麼有兩個帶下劃線的數字?哪一個引用了匿名方法索引?我的意思是,這是第一個(所以它的索引是0),但這裏有兩個0。如果是第二,就我有
0_1
,1_0
或其他什麼東西?
3)我有這樣的方法:
// Returns a Task that immediately throws when awaited, as soon as the token is cancelled
public static Task<T> GetWatchedTask<T>(this Task<T> awaitableTask, CancellationToken token)
{
return awaitableTask.ContinueWith(task => task.GetAwaiter().GetResult(), token);
}
而且我有這個堆棧跟蹤:
MyProject.Helpers.Extensions.TasksExtensions.<>c__3$1<System.__Canon>.<GetWatchedTask>b__3_0($Task$1<__Canon> task)
- 爲什麼沒有第二參數(tok en)出現在簽名中?
- 爲什麼類型
$Task$1
用「$」字符寫的?它是否像某種佔位符/地面指示符(如在正則表達式中),以便它可以在其他地方使用? (我的意思是,我看到$1<System.__Canon>
在我的猜測是該方法的返回類型)- 如果第一部分是方法的返回類型,爲什麼不是那裏所有的返回類型的方法呢?我有很多堆棧跟蹤方法,它們會返回一個值,但它們沒有相同的簽名。
.<>c__3$1<System.__Canon>
是什麼意思?從$1
和我想那將是Task<T>
返回類型,但那是什麼b__3_0
部分,因爲我沒有異步調用或事件處理程序?這是否意味着在這種情況下有所不同?
4)
Windows.UI.Xaml.Media.SolidColorBrush..ctor($Color color)
- 爲什麼參數類型與 '$' 字符開頭?它代表什麼?
5)我有這樣的其他方法:
public static async Task<ObservableCollection<SomeCustomClass>> LoadItemGroups(String parentId)
而這個堆棧跟蹤:
MyProject.SQLiteDatabase.SQLiteManager.<>c__DisplayClass142_3.<LoadGroups>b__3()
- 那是什麼
c__DisplayClass142_3
?這是一種用單一類型而不是三個單獨的類(Task,ObservableCollection,SomeCustomClass)表示返回類型的方法嗎? - 同樣,爲什麼我在這裏有
b__3
,在其他堆棧跟蹤中,它使用格式d_xxx
來指示異步代碼塊?
對不起,我希望這篇文章能夠幫助其他的UWP C#程序員。
非常感謝您的幫助!
編輯:這個問題應該不被視爲this other questions重複,因爲:
- 它呈現出不同的情況下(構造方法,泛型類型語法等),而不是隻是在尋求意義與特定類型的變量相關的某些默認關鍵字/符號
- 它具體詢問如何將給定的堆棧跟蹤與原始方法簽名進行比較,以及如何實現該步驟以實現該目的
- 它在不同的上下文中展示了不同的例子,而不是僅僅提出一個普遍的問題
- 順便說一下,「VS調試器魔術名稱」甚至被認爲是一個合適的問題標題?當尋找C#堆棧跟蹤符號的含義時,另一個用戶應該如何找到這個問題?
謝謝你,看起來對我來說很棒!仍然期待着Eric Lippert的另一個答案,因爲它可以增加更多的細節。 – Sergio0694
@Sergio0694希望你至少知道堆棧跟蹤中提到的方法是什麼。順便說一句,你有一個代碼來重現stacktrace中的$符號嗎?特別是在你的第4點。 – Evk