在控制台应用程序中调用HttpClient.GetAsync - 死锁

时间:2018-03-14 03:56:12

标签: c# .net async-await dotnet-httpclient

我搜索并看到很多帖子,我不知道为什么这个简单的控制台调用使用httpclient.getasync并等待它导致它无法完成。这是代码:

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);
        }
    }
}

如果我改为使用client.GetAsync(“https://www.google.com/”)。结果;并删除“await”(参见注释掉的代码)它会工作但是我相信这是不可能因为我正在将异步函数转换为同步。我已经看过其他关于这个的帖子和博客,并且它声称我正在尝试做的是正确的但是在运行示例应用程序时它不会那样。

2 个答案:

答案 0 :(得分:0)

问题是等待client.GetAsync,在获得结果后等待主线程空闲并且主线程正在等待client.GetAsync完成。

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

将告诉该client.GetAsync在其他线程上完成,然后将结果返回给主线程,以便不再有死锁。

答案 1 :(得分:0)

您可以在wait()中致电Main

但要小心,这只适用于console applications,并且会在ASP.NET,WPF,WinForms等UI应用程序中死锁......

public 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

  

此代码在控制台应用程序中可以正常工作,但会   从GUI或ASP.NET上下文调用死锁。