Typically, an asynchronous deadlock occurs in a user interface thread or in an ASP.NET context. I am trying to simulate a dead end in a console application so that I can unit test my library codes.
So here is my attempt:
class Program { private static async Task DelayAsync() { Console.WriteLine( "DelayAsync.Start" ); await Task.Delay( 1000 ); Console.WriteLine( "DelayAsync.End" ); }
So Deadlock () should cause a deadlock in the right context. To simulate an ASP.NET context, I use the DedicatedThreadSynchronisationContext from https://stackoverflow.com/a/167269/28 :
public sealed class DedicatedThreadSynchronisationContext : SynchronizationContext, IDisposable { public DedicatedThreadSynchronisationContext() { m_thread = new Thread( ThreadWorkerDelegate ); m_thread.Start( this ); } public void Dispose() { m_queue.CompleteAdding(); }
I set the context before calling Deadlock ():
SynchronizationContext.SetSynchronizationContext( new DedicatedThreadSynchronisationContext() );
I expect the code to hang on this line because it should capture the context:
await Task.Delay( 1000 );
However, it runs very well, and the program runs to the end, and it prints "Pressed". (Although the program hangs on DedicatedThreadSynchronisationContext.ThreadWorkerDelegate (), so it does not exist, but I consider it a minor problem.)
Why doesn't he create a deadlock? What is the correct way to simulate deadlock?
==========================================
EDIT
According to Luaanβs answer,
I used DedicatedThreadSynchronisationContext.Send () instead of creating a new thread:
Console.WriteLine( "Send.Start" ); var staContext = new DedicatedThreadSynchronisationContext(); staContext.Send( ( state ) => { Deadlock(); }, null ); Console.WriteLine( "Send.End" );
It allows Deadlock () to be launched under the context, so the βwaitβ captures the same context, thus deadlocking occurs.
Thanks Luaan!