-1

I am reading this article about deadlock, and I tried with my own code and it doesn't have deadlock issue. Why is that?

I am expecting:

  1. GetJsonAsync finishes await and about to return jsonString

  2. Main is executing jsonTask.Result and hold the context

  3. GetJsonAsync wants to return jsonString until context is available

  4. deadlock will happen

        public static void Main(string[] args)
        {
            var jsonTask = GetJsonAsync();
            int i = jsonTask.Result;
            Console.WriteLine(jsonTask.Result);
        }
    
        public static async Task<int> GetJsonAsync()
        {
            var jsonString = await ReturnIntAsync();
            return jsonString;
        }
    
        public static async Task<int> ReturnIntAsync()
        {
            int i = 0;
            await Task.Run(() => i++);
            return i;
        }
    
weijia_yu
  • 965
  • 4
  • 14
  • 31
  • 5
    Console applications do not have a SynchronizationContext, therefore, no context switch deadlock is provoked. The article clearly says "UI Example" and then "ASP.NET example" – Camilo Terevinto Jan 31 '19 at 23:30
  • @CamiloTerevinto thanks for replying, I added int assign, but still no deadlock – weijia_yu Jan 31 '19 at 23:34
  • You mean in main function, there is no SynchronizationContext? – weijia_yu Jan 31 '19 at 23:34
  • No, the SynchronizationContext is dependent on the framework you use, and those are numbered: WinForms, WPF, Xamarin and ASP.NET WebForms (as far as I remember) – Camilo Terevinto Jan 31 '19 at 23:37
  • 3
    Please read this blog post by *Stephen Toub (Mr. Parallel)* [Parallel Programming with .NET - await, SynchronizationContext, and Console Apps](https://blogs.msdn.microsoft.com/pfxteam/2012/01/20/await-synchronizationcontext-and-console-apps/) – TheGeneral Jan 31 '19 at 23:41

1 Answers1

3

It doesn't deadlock because there's no synchronizing SynchronizationContext, so the async method resumes executing on a thread pool thread, not the main thread.

Relevant quotes from the article (emphasis added):

Here’s the situation: remember from my intro post that after you await a Task, when the method continues it will continue in a context.

In the first case, this context is a UI context (which applies to any UI except Console applications). In the second case, this context is an ASP.NET request context...

For the UI example, the “context” is the UI context; for the ASP.NET example, the “context” is the ASP.NET request context. This type of deadlock can be caused for either “context”.

If you really want to deadlock a Console application this way, you can use AsyncContext from my AsyncEx library to install a single-threaded context on the main thread of your Console app.

Community
  • 1
  • 1
Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810