ironic ironic - 3 months ago 13
C# Question

How to find which method 'hangs' with async/await?

In the 'old' times it was very easy to track which method is hanging: just go to debugger, hit 'pause' button and go through stack traces.

Now however, if the problem is in the async method, this approach does not work - since the next piece of code to execute is buried somewhere in the continuation tasks (technically it does not even hang)... Is there a way for such easy debugging with tasks?

UPD.

Example:

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;
}
}


Notice that if you start it and hit 'pause' you will only see that DoHolyWar method is hanging, but you will not see where exactly. While if you replace 'await's with .Wait(), and do the same you will be able to examine the hanging stack trace. With this example it is quite simple, but in a real-world application it is often quite hard to find the problem. In particular a desktop application will have events loop running on the main thread, so even if something does 'hang', and you hit 'pause' you will get no clue about what went wrong.

Answer

In situations like this, what you can do is go to the debug dropdown menu, go to Windows, and choose the "Tasks" window (The default short cut key combo is "Ctrl+D, K").

This can give you a clue on what tasks are hanging.

enter image description here

Look for tasks that have abnormally long Duration values, that is a indication that something happened to the task and it is not completing. If you double click on the line it will take you to the await that is hung.

I don't know for sure why await BurnHeretics(); does not show up in the list for me, but I do know that this window will behave differently depending on your OS version because it relies on OS features to track some types of tasks. But at minimum this will show you that await DoHolyWarComplicatedDetails(); is hanging which will lead you to inspect DoHolyWarComplicatedDetails() which will lead you to inspect BurnHeretics(); which will lead you to your bug that is causing the hang.

Comments