简体   繁体   English

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

[英]Call HttpClient.GetAsync in console application - Deadlock

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. 我搜索并看到了很多帖子,但我不知道为什么使用httpclient.getasync进行此简单的控制台调用并等待它导致它无法完成。 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; 如果我更改为使用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. 并删除“ await”(请参见注释掉的代码),它将起作用,但是我认为这是不对的,因为我正在将异步函数转换为同步函数。 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. 我已经看过其他有关此的帖子和博客,它们都声称我试图做的是正确的,但是在运行示例应用程序时,事实并非如此。

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. 问题在于,等待client.GetAsync,获取结果后,等待主线程释放,而主线程等待client.GetAsync完成。

       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. 会告诉client.GetAsync在其他线程上完成,然后将结果返回到主线程,这样就不再有死锁了。

You can call wait() in Main . 您可以在Main调用wait()

But be carefull, this only works in console applications and will dead lock in UI applications like ASP.NET, WPF, WinForms... 但请注意,这仅适用于console applications并且会在UI应用程序(如ASP.NET,WPF,WinForms)中死锁。

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 MSDN

This code will work just fine in a console application but will deadlock when called from a GUI or ASP.NET context. 这段代码在控制台应用程序中可以很好地工作,但是当从GUI或ASP.NET上下文调用时将死锁。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM