Czytam niektóre raporty o awariach z aplikacji UWP (C#, skompilowanej z .NET Native) i ciężko jest mi zrozumieć dokładną składnię/format używany w śladach stosu. Próbowałem szukać przewodników w Internecie, ale nie wymyśliłem niczego przydatnego.Jak poprawnie odczytać/zinterpretować nieprzetworzony ślad stosu C#?
Oto kilka przykładów:
1)
MyProject.ViewModels.SomeViewModel.<OnLogin>d__69.MoveNext()
OnLogin
to nazwa metody wSomeViewModel
, więc dlaczego jest w nawiasach kątowych? Czy"ClassName".<"MethodName>..."
jest zwykłym sposobem wskazania metody instancji?- Rozumiem, że kompilator C# zamienia każdą porcję kodu między wywołania
await
w anonimowe metody i planuje je za pomocą kontynuacji, więc domyślam się, żed__69
wskazuje kontynuację asynchroniczną wewnątrz bieżącej metody.- Co oznacza skrót "d"?
- Czy te liczby są przypadkowe? Mam na myśli, że metoda nie ma 69
await
połączeń, więc domyślam się, że te liczby nie są sekwencyjne. Czy możliwe jest znalezienie dokładnej części w oryginalnej metodzie z tej liczby w zapisie stosu?
- Co to jest ta metoda
MoveNext()
na końcu? Jakiego rodzaju jest on wezwany?
2)
MyProject.UserControls.SomeControl.<.ctor>b__0_0
- wiem, że
.ctor
oznacza konstruktora obiektu, a patrząc na kod okazało się, żeb__0_0
oznacza anonimowego obsługi zdarzeń dodana wewnątrz konstruktor, taki jak ten:SomeEvent += (s, e) => Foo();
.- Co oznacza skrót "b"?
- Dlaczego są dwa numery z podkreślnikiem? Który z nich odnosi się do anonimowego indeksu metody? Mam na myśli, że jest pierwszy (więc jego indeks wynosi 0), ale są tu dwa 0. Gdyby to był drugi, czy miałbym
0_1
,1_0
lub coś innego?
3) mam tej metody:
// 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);
}
I mam ten ślad stosu:
MyProject.Helpers.Extensions.TasksExtensions.<>c__3$1<System.__Canon>.<GetWatchedTask>b__3_0($Task$1<__Canon> task)
- Dlaczego nie robi drugi parametr (tok pl) pojawi się w podpisie?
- Dlaczego typ
$Task$1
jest zapisany za pomocą znaku "$"?Czy jest to jak jakiś wskaźnik zastępczy/grunt (jak w regex), aby można go było używać również w innych miejscach? (Mam na myśli, widzę, że$1<System.__Canon>
w co myślę, jest metoda typ zwracany)- Jeśli to pierwsza część jest metoda typ zwracany, dlaczego nie jest tam dla wszystkich metod, które mają typ zwracany? Mam wiele śledzenia stosu z metodą zwracającą wartość, ale nie mają tego samego podpisu.
- Co to wszystko oznacza
.<>c__3$1<System.__Canon>
? Od$1
i prawdopodobnie to byłby typ zwracanyTask<T>
, ale co to jest za częśćb__3_0
, ponieważ nie mam wywołań asynchronicznych ani procedur obsługi zdarzeń? Czy to w tym przypadku oznacza coś innego?
4)
Windows.UI.Xaml.Media.SolidColorBrush..ctor($Color color)
- Dlaczego typ parametru zaczynają się od znaku '$'? Co to oznacza?
5) mam ten drugi sposób:
public static async Task<ObservableCollection<SomeCustomClass>> LoadItemGroups(String parentId)
i ten ślad stosu:
MyProject.SQLiteDatabase.SQLiteManager.<>c__DisplayClass142_3.<LoadGroups>b__3()
- co to
c__DisplayClass142_3
? Czy jest to sposób wskazania typu zwracanego z pojedynczym typem zamiast z trzech oddzielnych klas (Task, ObservableCollection, SomeCustomClass)? - Ponownie, dlaczego mam tutaj
b__3
, gdzie w innych śladach stosu użył formatud_xxx
do wskazania fragmentu kodu asynchronicznego?
Przepraszamy za wiele pytań, mam nadzieję, że ten post pomoże także innym programistom UWP C#.
Z góry dziękujemy za pomoc!
EDIT: kwestia ta powinna nie uznać duplikat this other questions ponieważ:
- Przedstawia różne przypadki (metody konstruktora typy generyczne składnia itp ..), a nie tylko z prośbą o znaczeniu niektórych domyślnych słów kluczowych/symboli związanych z pewnym typem zmiennych.
- W szczególności prosi o porównanie danego śladu stosu z oryginalnym podpisem metody oraz kroki, które należy wykonać, aby osiągnąć ten cel:
- Przedstawia różne przykłady w różnych kontekstach, zamiast po prostu zadawać ogólne pytanie:
- A przy okazji, w jaki sposób "magiczne nazwy VS debuggera" można nawet uznać za odpowiedni tytuł pytania? W jaki sposób inny użytkownik powinien znaleźć to pytanie, szukając znaczników śladów stosu C#?
Dzięki człowieku, wygląda mi to na wspaniałą odpowiedź! Z niecierpliwością czekam na kolejną odpowiedź Ericka Lipperta, ponieważ na pewno może dodać więcej szczegółów. – Sergio0694
@ Sergio0694 Mam nadzieję, że wiesz co najmniej może dowiedzieć się, co dokładnie jest wspomniana metoda w ślad stosu. Przy okazji, czy masz kod do odtworzenia tych znaków $ w stosie stacktrace? Zwłaszcza w twoim czwartym punkcie. – Evk