---
title: "How can I detect async deadlocks in a .NET Core web API?"  
description: "How can I detect async deadlocks in a .NET Core web API?"  
author: "John Smith"  
published: 2026-09-21  
updated: 2026-09-28  
canonical: https://answers.mindstick.com/qa/117253/how-can-i-detect-async-deadlocks-in-a-net-core-web-api  
category: "troubleshooting"  
tags: ["Debugging", ".NET", "async", "performance"]  
reading_time: 3 minutes  

---

# How can I detect async deadlocks in a .NET Core web API?

Async deadlocks in .NET are sneaky. They happen when you mix blocking calls like `.Result` or `.Wait()` with asynchronous code, and the synchronization context tries to reclaim a thread that’s already stuck waiting. In a web API, this often surfaces as a request that never returns, leaving connections pooled and threads exhausted.

## Answers

### Answer by Hemant Patel

## Why async deadlocks happen

Deadlocks in async code are sneaky because the thread context matters. In a classic ASP.NET Core request pipeline, if you block on an async method using `.Result` or `.Wait()` from a context that has a synchronization context—like the old ASP.NET request context—you can end up waiting forever. The continuation that should resume your work never gets scheduled because the thread you’re blocking on is the one that’s supposed to pick it up.

In modern .NET Core with the default `SynchronizationContext` null, this is less common, but it still happens when you call blocking code from within async methods, or when third-party libraries internally use `.Wait()`. The symptoms are usually thread starvation: requests hang, CPU stays low, and logs show nothing unusual.

## Common patterns that trigger them

Here are the usual suspects:

- Calling `.Result` or `.Wait()` on a `Task` inside an async controller action.
- Using `Task.Run` to “fix” a blocking call without understanding the context switch.
- Synchronous wrappers around async libraries (e.g., older ORMs or HTTP clients).
- Locking on a value type or `async` method return value, which causes an `InvalidOperationException` before a deadlock even forms.

## How to detect them in practice

Start with the runtime. When a deadlock occurs, the .NET runtime emits a **BCL deadlock** event. You can subscribe to this via `EventSource` or by enabling the diagnostic source:

```cs
// Enable diagnostic sources for deadlock detection
EventSource.CurrentGroup = "Microsoft-Windows-DotNETRuntime";
EventListener.Enable("Microsoft-Windows-DotNETRuntime", EventLevel.Verbose, (EventSourceOptions)0);

// Subscribe to deadlock events
Task.Run(async () =>
{
    await Task.Delay(1000);
    var deadlockSource = new EventListener("Microsoft-Windows-DotNETRuntime", "Microsoft-Windows-DotNETRuntime/Deadlock");
    deadlockSource.Enable();

    deadlockSource.AllEvents += (sender, args) =>
    {
        var payload = args.Payload;
        Console.WriteLine($"Deadlock detected: {payload}");
    };
});
```

In production, tools like **PerfView** or **[dotnet-trace](https://answers.mindstick.com/qa/117054/what-is-dotnet-trace-and-why-is-it-used)** capture these events without restarting the app. Look for `DEADLOCK` in the traces. If you see a cycle of waits involving your controller methods, you’ve found the culprit.

## Fixing the root cause

The fix is almost always to go fully async:

1. Remove every `.Result` and `.Wait()` from controller actions.
2. Return `Task<IActionResult>` and `await` your service calls.
3. If you must call a sync method, isolate it to a background thread pool thread with `Task.Run`, but verify that the downstream code is also async-friendly.

A quick sanity check is to run your API under a load test with `dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:0x3FF` and inspect the output. If no deadlock events appear, you’re likely clear.


---

Original Source: https://answers.mindstick.com/qa/117253/how-can-i-detect-async-deadlocks-in-a-net-core-web-api

Copyright © MindStick Software Pvt. Ltd. This Markdown version is provided for developers, AI systems, and offline reading.
