3

I searched and saw many posts and I don't know why this simple console call using httpclient.getasync and awaiting it causes it not to complete. here is the code:

using System;
using System.Net.Http;
using System.Threading.Tasks;

public class Program
{
    public static void Main(string[] args)
    {
        GetAPI().Wait();
        Console.WriteLine("Hello");
        //Console.ReadLine();
    }

    public static async Task GetAPI()
    {
        using (HttpClient client = new HttpClient())
        {
            var response = await client.GetAsync("https://www.google.com/");
            //var response = client.GetAsync("https://www.google.com/").Result

            string content = await response.Content.ReadAsStringAsync();
            Console.WriteLine(content);
        }
    }
}

If I change to use client.GetAsync("https://www.google.com/").Result; and remove "await" (see commented out code) it will work however I believe that is a no no because I am making an asynchronous function into synchronous. I've seen other posts and blogs about this and it all claims what I am trying to do is correct but when running the example app it just doesn't turn out that way.

Legends
  • 21,202
  • 16
  • 97
  • 123
user3799149
  • 39
  • 1
  • 2
  • Possible duplicate of [An async/await example that causes a deadlock](https://stackoverflow.com/questions/15021304/an-async-await-example-that-causes-a-deadlock) – ProgrammingLlama Mar 14 '18 at 03:59
  • [Also this](https://stackoverflow.com/questions/38446331/deadlock-with-async-await) and [this](https://stackoverflow.com/questions/17248680/await-works-but-calling-task-result-hangs-deadlocks) – ProgrammingLlama Mar 14 '18 at 03:59
  • It might be a deadlock issue but I am trying to avoid it by not calling .Result in the GetAPI call. I am trying to use async and await to prevent deadlock. I only used wait() in the main function of the console program which needs to block to prevent the program from exiting. The other threads you linked all were calling Result which I am refraining from. – user3799149 Mar 14 '18 at 04:30
  • 1
    This application should not deadlock (and I even tried it - it does not for me). – Evk Mar 14 '18 at 07:23

2 Answers2

3

You can call wait() in Main.

But be carefull, this only works in console applications and will dead lock in UI applications like WPF, WinForms or in ASP.NET context...

public static void Main(string[] args)
{
    
    try
    {           
         var t =  GetAPI();
         t.Wait();
         Console.WriteLine(t.Result);   
    }
    catch (Exception ex)
    {
         Console.WriteLine(ex.Message);  
    }
      
}

public static async Task<string> GetAPI()
{
   using (HttpClient client = new HttpClient())
   {
      var response = await client.GetAsync("https://www.google.com/"); 
      string content = await response.Content.ReadAsStringAsync(); 
  
     return content;
   }
}

MSDN

This code will work just fine in a console application but will deadlock when called from a GUI or ASP.NET context.

Legends
  • 21,202
  • 16
  • 97
  • 123
  • I don't see the difference between this and the code the OP is already using. He's already using `Wait()`. Can you explain? – John Wu Sep 16 '22 at 17:02
1

The issue is that awaiting the client.GetAsync, after getting the result is waiting for main thread to be free and main thread is waiting for client.GetAsync to complete.

       var response = await client.GetAsync("https://www.google.com/").ConfigureAwait(false);
       string content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

Will tell that client.GetAsync to complete on other thread and then return the result back to main thread so that no more dead lock.

Devesh
  • 4,500
  • 1
  • 17
  • 28
  • This seems to have done the trick, I think I saw this suggestion for another thread as well but when I applied it did not work for some reason. I had to go back and make sure there was no other "sync" calls that was preventing this from working. – user3799149 Mar 14 '18 at 19:21