Skip to content

Instantly share code, notes, and snippets.

@noseratio
Last active November 9, 2023 19:16
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save noseratio/50437eb11f950ade1a64a95a53a4caee to your computer and use it in GitHub Desktop.
Save noseratio/50437eb11f950ade1a64a95a53a4caee to your computer and use it in GitHub Desktop.
A simple helper SynchronizationContext to debug deadlocks
// A helper SynchronizationContext to debug deadlocks by @noseratio
// If you install DebugSyncContext at the very beginning of your console app and run it under debugger,
// it should stop where the deadlock is happening, with a better access to the stack frame.
using System.Diagnostics;
SynchronizationContext.SetSynchronizationContext(new DebugSyncContext());
Console.WriteLine("Hello!");
await Task.Delay(100);
await Task.Delay(200);
await Task.Delay(300);
// break at DebugSyncContext.Wait
Task.Delay(400).GetAwaiter().GetResult();
await Task.Delay(500);
Console.WriteLine("Bye!");
class DebugSyncContext: SynchronizationContext
{
public DebugSyncContext()
{
base.SetWaitNotificationRequired();
}
public override void Post(SendOrPostCallback d, object? state)
{
ThreadPool.QueueUserWorkItem(_ =>
{
var sc = SynchronizationContext.Current;
SynchronizationContext.SetSynchronizationContext(this);
try
{
d(state);
}
finally
{
SynchronizationContext.SetSynchronizationContext(sc);
}
});
}
public override void Send(SendOrPostCallback d, object? state)
{
Debugger.Break();
throw new NotImplementedException(nameof(Send));
}
public override int Wait(nint[] waitHandles, bool waitAll, int millisecondsTimeout)
{
Debugger.Break();
return base.Wait(waitHandles, waitAll, millisecondsTimeout);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment