Last active
November 9, 2023 19:16
-
-
Save noseratio/50437eb11f950ade1a64a95a53a4caee to your computer and use it in GitHub Desktop.
A simple helper SynchronizationContext to debug deadlocks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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