簡體   English   中英

在控制台應用程序中調用HttpClient.GetAsync-死鎖

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

我搜索並看到了很多帖子,但我不知道為什么使用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/”).Result ; 並刪除“ await”(請參見注釋掉的代碼),它將起作用,但是我認為這是不對的,因為我正在將異步函數轉換為同步函數。 我已經看過其他有關此的帖子和博客,它們都聲稱我試圖做的是正確的,但是在運行示例應用程序時,事實並非如此。

問題在於,等待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在其他線程上完成,然后將結果返回到主線程,這樣就不再有死鎖了。

您可以在Main調用wait()

但請注意,這僅適用於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

這段代碼在控制台應用程序中可以很好地工作,但是當從GUI或ASP.NET上下文調用時將死鎖。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM