In den "alten" Zeiten war es sehr einfach zu verfolgen, welche Methode hängt: Gehen Sie einfach zum Debugger, klicken Sie auf "Pause" und gehen Sie durch die Stack-Traces.Wie finde ich heraus, welche Methode 'hängt' mit async/abwarten?
Jetzt, wenn das Problem in der asynchronen Methode ist, funktioniert dieser Ansatz nicht - da der nächste Stück Code ausgeführt wird irgendwo in den Fortsetzungsaufgaben begraben (technisch hängt es nicht einmal) ... Gibt es ein Weg für so einfaches Debuggen mit Aufgaben?
UPD.
Beispiel:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private async void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
{
await DoHolyWar();
MessageBox.Show("Holy war complete!");
}
public static async Task DoHolyWar()
{
await DoHolyWarComplicatedDetails();
Console.WriteLine("Victory!");
}
public static async Task DoHolyWarComplicatedDetails()
{
await BurnHeretics();
}
public static Task BurnHeretics()
{
var tcs = new TaskCompletionSource<object>();
// we should have done this, but we forgot
// tcs.SetResult(null);
return tcs.Task;
}
}
Beachten Sie, dass, wenn Sie es starten und drücken Sie ‚Pause‘ Sie werden sehen, dass DoHolyWar Methode hängt, aber Sie werden nicht, wo genau sehen. Wenn Sie 'wait' mit '.Wait()' ersetzen und dasselbe tun, können Sie die hängende Stack-Spur untersuchen. Mit diesem Beispiel ist es ziemlich einfach, aber in einer realen Anwendung ist es oft ziemlich schwierig, das Problem zu finden. Insbesondere bei einer Desktop-Anwendung wird die Ereignisschleife im Hauptthread ausgeführt. Wenn also etwas "hängt" und Sie auf "Pause" klicken, werden Sie keine Ahnung haben, was falsch gelaufen ist.
Als allgemeine Regel gilt, dann ist es fast immer derjenige, der als ob Asynchron durch expliziten Aufruf 'Wait' oder' Result' existiert nicht zu handeln versucht. –
Ah, ok. Es ist also nicht wirklich ein "Hang", da Ihr Programm immer noch reaktiv ist (wenn Sie ein WPF- oder Winforms-Programm gemacht hätten und "DoHolyWar()" erwartet hätten, würde das Programm immer noch reagieren. Vielleicht möchten Sie Ihre Frage ändern Anstatt eine Konsolen-App zu sein, um deutlicher zu machen, dass Sie nicht von einem tatsächlichen "Hang" sprechen, wird festgestellt, dass ein 'SetResult' nie aufgerufen wird. –
In der Tat habe ich Ihre Frage aktualisiert, um dies zu tun, wenn Sie es nicht mögen, fühlen Sie sich frei, um die Änderung rückgängig zu machen. –