A deadlock is a situation where two or more threads (or tasks) are
waiting for each other to release resources, and none of them ever proceed — resulting in a permanent blocking cycle.
In .NET, deadlocks can occur in:
Multithreading (e.g., lock)
Asynchronous code (async/await)
Database transactions
Threading Deadlock Example
object lockA = new object();
object lockB = new object();
void Thread1()
{
lock (lockA)
{
Thread.Sleep(100); // Give Thread2 a chance to lock B
lock (lockB)
{
// do something
}
}
}
void Thread2()
{
lock (lockB)
{
Thread.Sleep(100);
lock (lockA) // Deadlock: Thread1 holds A, waits for B; Thread2 holds B, waits for A
{
// do something
}
}
}
Deadlock in Async/Await
public string GetData()
{
return GetDataAsync().Result; // blocks UI thread
}
public async Task<string> GetDataAsync()
{
await Task.Delay(1000); // Tries to resume on captured (blocked) UI thread → deadlock
return "done";
}
This causes a deadlock especially in UI apps like WinForms/WPF.
How to Prevent Deadlocks
1. Always Acquire Locks in the Same Order
Avoid circular waits.
lock (lockA)
{
lock (lockB)
{
// Safe if always A → B
}
}
2. Avoid Synchronous Blocking on Async Code
Prefer await over .Result or .Wait()
public async Task<string> GetDataAsync()
{
await Task.Delay(1000);
return "done";
}
// Good
string result = await GetDataAsync();
3. Use Timeout with Locks
bool lockTaken = Monitor.TryEnter(lockA, TimeSpan.FromSeconds(2));
if (lockTaken)
{
try
{
// do work
}
finally
{
Monitor.Exit(lockA);
}
}
else
{
// handle lock timeout
}
4. Use ConfigureAwait(false) in Library Code
Prevents deadlocks by not capturing the synchronization context:
We use cookies to ensure you have the best browsing experience on our website. By using our site, you
acknowledge that you have read and understood our
Cookie Policy &
Privacy Policy.
In .NET, deadlocks can occur in:
lock)async/await)Threading Deadlock Example
Deadlock in Async/Await
How to Prevent Deadlocks
1. Always Acquire Locks in the Same Order
Avoid circular waits.
2. Avoid Synchronous Blocking on Async Code
Prefer
awaitover.Resultor.Wait()3. Use Timeout with Locks
4. Use
ConfigureAwait(false)in Library CodePrevents deadlocks by not capturing the synchronization context:
5. Use
SemaphoreSlimInstead oflockfor AsyncSummary
.Result, use timeouts, preferawait, useConfigureAwait(false)